# ==============================================================================
# OpenCompletion Activity YAML Specification
# ==============================================================================
# This document defines ALL supported mechanics for creating educational
# activities in the OpenCompletion system.
#
# Version: 1.0
# Last Updated: 2025-01-10
# ==============================================================================

# ==============================================================================
# ACTIVITY ROOT LEVEL
# ==============================================================================
# These fields apply to the entire activity

# Maximum number of times a user can attempt each step before auto-advancing
# Default: 3
# Optional
default_max_attempts_per_step: 3

# Model to use for categorizing user responses into buckets
# Default: "MODEL_1" (Hermes-3-Llama-3.1-8B)
# Optional
classifier_model: "MODEL_1"

# Model to use for generating AI feedback
# Default: "MODEL_1" (Hermes-3-Llama-3.1-8B)
# Optional
# Tip: Use faster models (MODEL_1) for classification, specialized models (MODEL_3) for feedback
feedback_model: "MODEL_1"

# Global rubric for evaluating student responses across all steps
# This provides consistent evaluation criteria
# Optional
tokens_for_ai_rubric: |
  You are helping students learn about [TOPIC].

  Evaluate their responses based on:
  - Understanding of core concepts
  - Clarity of explanation
  - Critical thinking demonstrated

  Be encouraging and constructive!

# ==============================================================================
# SECTIONS
# ==============================================================================
# Activities are organized into sections, which contain steps
# Required: At least one section

sections:
  # Each section must have a unique section_id
  - section_id: "introduction"  # REQUIRED - Unique identifier
    title: "Getting Started"    # REQUIRED - Human-readable title

    # Steps are the individual interactions within a section
    steps:
      # ========================================================================
      # STEP TYPE 1: CONTENT-ONLY STEP
      # ========================================================================
      # Displays information and automatically advances
      # No user interaction required

      - step_id: "welcome"           # REQUIRED - Unique within this section
        title: "Welcome"             # REQUIRED - Human-readable title

        # Content blocks are displayed to the user
        # Supports markdown formatting
        content_blocks:               # REQUIRED for content-only steps
          - "# Welcome to the Activity! 🎉"
          - ""
          - "This activity will teach you about [TOPIC]."
          - ""
          - "**What you'll learn:**"
          - "- Concept 1"
          - "- Concept 2"
          - "- Concept 3"
          - ""
          - "Let's get started!"

        # Content-only steps automatically advance to the next step
        # No question, buckets, or transitions needed

      # ========================================================================
      # STEP TYPE 2: QUESTION STEP
      # ========================================================================
      # Interactive step that requires user response

      - step_id: "question_example"
        title: "Your First Question"

        # Optional: Content blocks can appear before the question
        content_blocks:
          - "## Background Information"
          - "Before we ask the question, here's some context..."

        # The question asked to the user
        question: "What is your name?"  # REQUIRED for question steps

        # Instructions for the AI on how to categorize the user's response
        # The AI will read this and place the response into one of the buckets
        tokens_for_ai: |              # REQUIRED for question steps
          Categorize the user's response:

          - name_provided: They gave a name (any name is acceptable)
          - set_language: They want to change language preference
          - off_topic: Their response is unrelated to the question

          Be generous in accepting names - nicknames, full names, etc.

        # Instructions for generating feedback after categorization
        # This is used when creating ai_feedback in transitions
        feedback_tokens_for_ai: |     # Optional but recommended
          Welcome the user by their name warmly!
          Make them feel comfortable and ready to learn.

          Example: "Welcome, [name]! Great to have you here!"

        # List of possible categories (buckets) for user responses
        # Every response will be categorized into one of these
        buckets:                       # REQUIRED for question steps
          - name_provided
          - set_language
          - off_topic
          - emergency      # Random bucket - also in buckets list
          - surprise       # Random bucket - also in buckets list
          - bonus          # Random bucket - also in buckets list

        # ======================================================================
        # RANDOM BUCKETS (Optional)
        # ======================================================================
        # Probabilistic events that can trigger alongside user responses
        # Random rolls happen BEFORE categorization
        # Multiple random buckets can trigger simultaneously

        random_buckets:               # Optional
          # Each random bucket must also appear in the main buckets list above
          emergency:
            probability: 0.05          # 5% chance (0.0 to 1.0)

          surprise:
            probability: 0.10          # 10% chance

          bonus:
            probability: 0.03          # 3% chance

        # Processing Order:
        # 1. Random buckets rolled
        # 2. User response categorized
        # 3. User's bucket processed FIRST
        # 4. Random buckets processed in order they triggered
        # 5. Metadata accumulates across all transitions
        # 6. Last transition's navigation wins

        # ======================================================================
        # TRANSITIONS
        # ======================================================================
        # Define what happens for each bucket
        # REQUIRED: One transition per bucket (including random buckets)

        transitions:
          # ==================================================================
          # TRANSITION STRUCTURE
          # ==================================================================
          # Each bucket name maps to a transition configuration

          name_provided:
            # ----------------------------------------------------------------
            # CONTENT BLOCKS (Optional)
            # Static text displayed immediately
            # ----------------------------------------------------------------
            content_blocks:
              - "Great! Let's continue."

            # ----------------------------------------------------------------
            # AI FEEDBACK (Optional)
            # Dynamic feedback generated by the AI
            # Uses feedback_tokens_for_ai from the step
            # ----------------------------------------------------------------
            ai_feedback:
              tokens_for_ai: |
                Generate personalized feedback based on their response.
                Reference their specific answer to show you're paying attention.
                Be encouraging!

            # ----------------------------------------------------------------
            # METADATA OPERATIONS (Optional)
            # Modify the persistent metadata that follows the user
            # ----------------------------------------------------------------

            # ADD or UPDATE metadata keys
            metadata_add:
              # Store the exact user response
              user_name: "the-users-response"

              # Numeric increment: n+5 means "add 5 to existing value (or 0)"
              score: "n+5"

              # Numeric decrement: n-3 means "subtract 3 from existing value"
              lives: "n-3"

              # String concatenation: n+,value means "append value to comma-separated list"
              achievements: "n+,first_question"
              # If achievements was "started", becomes "started,first_question"
              # If achievements was empty, becomes "first_question"

              # String removal: n-,value means "remove value from comma-separated list"
              # pending_tasks: "n-,intro"  # Removes "intro" from list

              # Random numeric increment: n+random(1,10) adds random number between 1 and 10
              bonus_points: "n+random(1,10)"

              # Static value
              step_completed: "true"

              # Timestamp or any string
              last_active: "2025-01-10"

            # TEMPORARY metadata (removed at end of step)
            # Useful for one-time values that don't persist
            metadata_tmp_add:
              temp_hint: "Remember this for the next question!"
              temp_score: "n+2"  # All same operations as metadata_add work here

            # REMOVE specific metadata keys
            metadata_remove:
              - old_key
              - another_key
            # Or single key:
            # metadata_remove: "single_key"

            # CLEAR all metadata (use with caution!)
            metadata_clear: true

            # RANDOM metadata - pick ONE random key-value pair
            metadata_random:
              random_event: "event_a"  # One of these will be chosen
              random_event: "event_b"
              random_event: "event_c"

            # TEMPORARY random metadata - pick from list, remove at end of step
            metadata_tmp_random:
              dice_roll: [1, 2, 3, 4, 5, 6]  # One value chosen randomly
              color_choice: ["red", "blue", "green"]

            # ----------------------------------------------------------------
            # METADATA CONDITIONS (Optional)
            # Only execute this transition if conditions are met
            # ----------------------------------------------------------------
            metadata_conditions:
              level: 5           # metadata.level must equal 5
              has_key: "yes"     # metadata.has_key must equal "yes"
              # All conditions must be true (AND logic)

            # ----------------------------------------------------------------
            # METADATA FEEDBACK FILTER (Optional)
            # Only show AI feedback if specific metadata keys exist
            # ----------------------------------------------------------------
            metadata_feedback_filter:
              - "achievement_unlocked"
              - "bonus_available"
            # AI feedback only generated if these keys are present in metadata

            # ----------------------------------------------------------------
            # PROCESSING SCRIPT (Optional)
            # Execute Python code to perform complex logic
            # ----------------------------------------------------------------
            # Note: processing_script is defined at STEP level, not transition level
            # Use run_processing_script: true to execute it for this transition
            run_processing_script: true

            # ----------------------------------------------------------------
            # NAVIGATION (Optional)
            # Where to go next
            # ----------------------------------------------------------------
            next_section_and_step: "introduction:processing_example"
            # Format: "section_id:step_id"
            # If omitted, stays on current step (useful for retry loops)
            # If ALL transitions omit this, activity terminates

            # ----------------------------------------------------------------
            # ATTEMPT COUNTING (Optional)
            # Whether this transition counts toward max_attempts_per_step
            # ----------------------------------------------------------------
            counts_as_attempt: false  # Default: true
            # Set to false for:
            # - Hints that let user retry
            # - Language changes
            # - Clarifying questions
            # Set to true for:
            # - Wrong answers
            # - Correct answers
            # - Progress-making choices

          # ==================================================================
          # SPECIAL BUCKETS
          # ==================================================================

          # Language change bucket (standard pattern)
          set_language:
            content_blocks:
              - "Language preference updated."
            metadata_add:
              language: "the-users-response"
            counts_as_attempt: false      # Don't penalize language changes
            next_section_and_step: "introduction:question_example"  # Retry same question

          # Off-topic response (retry pattern)
          off_topic:
            content_blocks:
              - "I didn't understand that. Could you try again?"
            next_section_and_step: "introduction:question_example"  # Retry
            # counts_as_attempt: true (default) - wrong answers count

          # Random event transitions
          emergency:
            ai_feedback:
              tokens_for_ai: |
                🚨 EMERGENCY EVENT!
                Describe the emergency dramatically.
                Show how the user handles it with their previous choice.
            metadata_add:
              emergencies_handled: "n+1"
              random_events: "n+,emergency"
            counts_as_attempt: false      # Random events don't count as attempts
            # No next_section_and_step - uses user's navigation

          surprise:
            ai_feedback:
              tokens_for_ai: |
                ✨ SURPRISE EVENT!
                Something unexpected happens!
            metadata_add:
              surprises_encountered: "n+1"
              bonus_points: "n+random(5,15)"
            counts_as_attempt: false

          bonus:
            ai_feedback:
              tokens_for_ai: |
                🎁 BONUS EVENT!
                You earned a bonus!
            metadata_add:
              bonuses_collected: "n+1"
            counts_as_attempt: false

      # ========================================================================
      # PROCESSING SCRIPTS
      # ========================================================================
      # Python code executed during transitions
      # Defined at step level, triggered by run_processing_script: true

      - step_id: "processing_example"
        title: "Processing Script Demo"
        question: "Enter a number:"
        tokens_for_ai: "Categorize as 'number' if numeric, 'invalid' otherwise"
        buckets: [number, invalid]

        # Pre-script runs BEFORE categorization
        # Has access to user_response in metadata
        pre_script: |
          # Available: metadata dict (read/write), user_response
          result = {}

          # Parse user input
          try:
              value = int(metadata.get("user_response", "0"))
              result["parsed_value"] = value
              result["is_even"] = value % 2 == 0
          except ValueError:
              result["parsed_value"] = None
              result["is_even"] = False

          # Return dict of values to add to metadata
          return result

        # Processing script runs DURING transition (if run_processing_script: true)
        # Has access to user_response in metadata
        processing_script: |
          # Available: metadata dict (read/write)
          result = {}

          # Complex calculations
          score = metadata.get("score", 0)
          multiplier = metadata.get("multiplier", 1)
          result["final_score"] = score * multiplier

          # Conditional logic
          if result["final_score"] > 100:
              result["achievement"] = "high_scorer"

          return result

        transitions:
          number:
            run_processing_script: true  # Triggers processing_script above
            ai_feedback:
              tokens_for_ai: "Confirm their number and show calculated results from metadata"
            metadata_add:
              attempts: "n+1"
            next_section_and_step: "introduction:feedback_prompts_example"

          invalid:
            content_blocks:
              - "Please enter a valid number."
            next_section_and_step: "introduction:processing_example"

      # ========================================================================
      # FEEDBACK PROMPTS (Multi-Agent Feedback)
      # ========================================================================
      # New system for having multiple AI agents provide feedback
      # Each agent has their own personality and perspective

      - step_id: "feedback_prompts_example"
        title: "Multi-Agent Feedback Demo"
        question: "Design a solution to [PROBLEM]"
        tokens_for_ai: |
          Categorize as:
          - excellent: Comprehensive, creative solution
          - good: Solid solution with minor gaps
          - needs_work: Incomplete or flawed
        buckets: [excellent, good, needs_work]

        # Define multiple feedback agents
        # Each has their own name, emoji, and personality
        feedback_prompts:
          # Technical reviewer - focuses on implementation
          - name: "Tech Lead"
            emoji: "🔧"
            tokens_for_ai: |
              You are a senior technical architect.
              Review solutions for:
              - Technical feasibility
              - Scalability concerns
              - Implementation complexity
              Be constructive but thorough.
            system_prompt: |
              You are a senior technical architect reviewing student solutions.

            # Conditions for when this agent provides feedback
            metadata_conditions:
              level: "advanced"  # Only for advanced students

            # Buckets this agent responds to
            buckets_to_respond: [excellent, good]  # Skips needs_work

          # Creative reviewer - focuses on innovation
          - name: "Design Guru"
            emoji: "🎨"
            tokens_for_ai: |
              You are a creative design expert.
              Evaluate solutions for:
              - Innovation and originality
              - User experience considerations
              - Aesthetic appeal
              Inspire them to think outside the box!
            system_prompt: |
              You are a creative design expert evaluating student work.

            # This agent responds to all buckets (default)

          # Encouraging mentor - provides emotional support
          - name: "Mentor"
            emoji: "🌟"
            tokens_for_ai: |
              You are an encouraging mentor.
              Provide:
              - Emotional support
              - Encouragement to continue
              - Recognition of effort
              Always be positive and uplifting!
            system_prompt: |
              You are an encouraging mentor supporting students.

            # Always include this agent's feedback
            always_include: true

        # Legacy feedback tokens (combined with feedback_prompts if both present)
        feedback_tokens_for_ai: |
          Provide overall feedback on their solution.
          This is combined with the multi-agent feedback.

        transitions:
          excellent:
            # Multi-agent feedback automatically generated
            # Each agent in feedback_prompts provides their perspective
            metadata_add:
              score: "n+10"
            next_section_and_step: "advanced:coding_challenge"

          good:
            metadata_add:
              score: "n+5"
            next_section_and_step: "advanced:coding_challenge"

          needs_work:
            content_blocks:
              - "Let's try this again with some hints..."
            next_section_and_step: "introduction:feedback_prompts_example"

# ==============================================================================
# STEP-LEVEL MODEL OVERRIDES
# ==============================================================================
# Steps can override the activity-level classifier and feedback models

  - section_id: "advanced"
    title: "Advanced Section"
    steps:
      - step_id: "coding_challenge"
        title: "Write Code"

        # Override classifier model for this step
        classifier_model: "MODEL_1"  # Fast classification

        # Override feedback model for this step
        feedback_model: "MODEL_3"    # Qwen3-Coder for code review

        question: "Write a function to solve [PROBLEM]"
        tokens_for_ai: "Categorize as correct/incorrect based on solution quality"
        buckets: [correct, incorrect]
        transitions:
          correct:
            ai_feedback:
              tokens_for_ai: |
                Review their code professionally.
                Provide specific feedback on:
                - Code style and readability
                - Algorithmic efficiency
                - Edge case handling
            next_section_and_step: "conclusion:goodbye_content"
          incorrect:
            ai_feedback:
              tokens_for_ai: "Provide hints without giving away the solution"
            next_section_and_step: "advanced:coding_challenge"

# ==============================================================================
# TERMINATION PATTERNS
# ==============================================================================
# Activities can terminate in several ways

  - section_id: "conclusion"
    title: "Wrap Up"
    steps:
      # ========================================================================
      # TERMINATION 1: Content-Only Final Step
      # ========================================================================
      # Simplest termination - just display content

      - step_id: "goodbye_content"
        title: "Thank You!"
        content_blocks:
          - "# Thank You for Participating! 🎉"
          - ""
          - "You've completed the activity!"
          - "Your final score: check metadata.score"
          - ""
          - "Come back anytime!"
        # No question = auto-terminates

      # ========================================================================
      # TERMINATION 2: Final Reflection Question
      # ========================================================================
      # Last question with no onward navigation

      - step_id: "reflection"
        title: "Final Reflection"
        question: "What did you learn today?"
        tokens_for_ai: |
          Categorize their reflection as:
          - thoughtful: Deep, meaningful reflection
          - brief: Short but genuine
          - off_topic: Not answering the question
        buckets: [thoughtful, brief, off_topic]
        transitions:
          thoughtful:
            ai_feedback:
              tokens_for_ai: "Celebrate their learning and growth!"
            metadata_add:
              activity_completed: "true"
            # No next_section_and_step = terminates

          brief:
            ai_feedback:
              tokens_for_ai: "Thank them for their time and effort!"
            metadata_add:
              activity_completed: "true"
            # No next_section_and_step = terminates

          off_topic:
            content_blocks:
              - "Please reflect on what you learned in this activity."
            next_section_and_step: "conclusion:reflection"  # Retry

      # ========================================================================
      # TERMINATION 3: Explicit Exit Path
      # ========================================================================
      # Provide clear exit option

      - step_id: "play_again"
        title: "Continue?"
        question: "Would you like to play again or exit?"
        tokens_for_ai: "Categorize as 'again' or 'exit'"
        buckets: [again, exit]
        transitions:
          again:
            metadata_clear: true  # Reset game state
            next_section_and_step: "introduction:welcome"  # Restart

          exit:
            next_section_and_step: "conclusion:goodbye_content"  # Jump to end

# ==============================================================================
# METADATA SPECIAL VALUES
# ==============================================================================
# Reference guide for all metadata operations

# String Operations:
# ------------------
# "the-users-response"         → Exact text of user's answer
# "n+,value"                   → Append to comma-separated list
# "n-,value"                   → Remove from comma-separated list

# Numeric Operations:
# -------------------
# "n+5"                        → Add 5 to existing value (or 0)
# "n-3"                        → Subtract 3 from existing value
# "n+random(1,10)"             → Add random number between 1 and 10

# Static Values:
# --------------
# "any string"                 → Store literal string
# 42                           → Store integer
# true / false                 → Store boolean

# ==============================================================================
# ADVANCED FEATURES (New in v2.0)
# ==============================================================================

# ==============================================================================
# TEMPLATE VARIABLES
# ==============================================================================
# Use {{variable_name}} syntax to insert dynamic values into content

# Available in: content_blocks, questions, ai_feedback tokens

# Built-in Variables:
# -------------------
# {{current_attempt}}        → Current attempt number (1, 2, 3...)
# {{max_attempts}}           → Maximum attempts allowed for this step
# {{attempts_remaining}}     → How many attempts left (max - current)
# {{current_section}}        → Current section_id
# {{current_step}}           → Current step_id
# {{username}}               → Name of the user who last responded

# Metadata Variables:
# -------------------
# {{metadata.key_name}}      → Access any metadata value
# {{metadata.score}}         → Example: access score
# {{metadata.player_name}}   → Example: access player name

# Example Usage:
content_blocks:
  - "## Your Progress"
  - "Welcome back, {{metadata.player_name}}!"
  - "Score: {{metadata.score}}"
  - "Level: {{metadata.level}}"
  - "Attempt {{current_attempt}} of {{max_attempts}}"
  - "You have {{attempts_remaining}} tries remaining"

question: "{{metadata.character_name}} asks: What will you do?"

# Templates work in:
# - step content_blocks
# - transition content_blocks
# - question text
# - ai_feedback tokens_for_ai (for context, not rendered directly)

# ==============================================================================
# CONDITIONAL CONTENT BLOCKS
# ==============================================================================
# Show/hide content blocks based on metadata conditions

# Format: Each content block can be a string OR an object with conditions

content_blocks:
  # Simple string - always shown
  - "This is always displayed"

  # Conditional block - only shown if conditions met
  - text: "You're doing great! Keep going!"
    show_if:
      score_gte: 50  # Only show if score >= 50

  - text: "Need more practice. Don't give up!"
    show_if:
      score_lt: 50  # Only show if score < 50

  - text: "You found the secret key! 🗝️"
    show_if:
      inventory_contains: "key"  # Only if inventory contains "key"

  - text: "Welcome, warrior! ⚔️"
    show_if:
      class: "warrior"  # Only if metadata.class equals "warrior"

  - text: "Welcome, mage! 🔮"
    show_if:
      class: "mage"

# Conditional blocks reduce step duplication - one step, multiple paths!

# ==============================================================================
# ADVANCED METADATA CONDITIONS
# ==============================================================================
# Rich comparison operators for metadata_conditions

# Previously only supported equality:
metadata_conditions:
  level: 5  # metadata.level must equal 5

# Now supports:
# --------------

# Equality & Inequality:
metadata_conditions:
  status: "active"           # Equal to "active"
  status_ne: "inactive"      # Not equal to "inactive"

# Numeric Comparisons:
metadata_conditions:
  score_gte: 100             # Greater than or equal to 100
  score_gt: 99               # Greater than 99
  score_lt: 200              # Less than 200
  score_lte: 199             # Less than or equal to 199
  level_between: [5, 10]     # Between 5 and 10 (inclusive)

# String Operations:
metadata_conditions:
  inventory_contains: "sword"      # Comma-separated list contains "sword"
  inventory_not_contains: "poison" # List does NOT contain "poison"
  name_matches: "^[A-Z]"           # Regex match (starts with capital)

# Existence Checks:
metadata_conditions:
  has_key_exists: true       # Key "has_key" must exist in metadata
  temp_flag_not_exists: true # Key "temp_flag" must NOT exist

# Boolean Checks:
metadata_conditions:
  is_admin: true             # metadata.is_admin must be true
  is_locked: false           # metadata.is_locked must be false

# Combining Multiple Conditions (ALL must be true):
metadata_conditions:
  score_gte: 100
  level_gte: 5
  inventory_contains: "key"
  quest_completed: true
# All four conditions must be met

# ==============================================================================
# CONDITIONAL NAVIGATION
# ==============================================================================
# Choose different paths based on metadata state

# OLD WAY (still works):
transitions:
  answer_provided:
    next_section_and_step: "section_2:step_1"

# NEW WAY - Conditional branches:
transitions:
  answer_provided:
    next_section_and_step:
      - if:
          score_gte: 100
        goto: "expert:challenge"

      - elif:
          score_gte: 50
        goto: "intermediate:lesson"

      - elif:
          score_gte: 25
        goto: "beginner:practice"

      - else:
        goto: "tutorial:basics"

# Another example: Quest completion paths
transitions:
  quest_complete:
    next_section_and_step:
      - if:
          all_secrets_found: true
          perfect_score: true
        goto: "endings:perfect_ending"

      - elif:
          all_secrets_found: true
        goto: "endings:good_ending"

      - elif:
          quest_failed: true
        goto: "endings:bad_ending"

      - else:
        goto: "endings:neutral_ending"

# Conditions use same operators as metadata_conditions:
# - Equality: key: value
# - Comparisons: key_gte, key_gt, key_lt, key_lte
# - String ops: key_contains, key_not_contains, key_matches
# - Existence: key_exists, key_not_exists
# - Boolean: key: true/false

# ==============================================================================
# PROGRESSIVE HINTS SYSTEM
# ==============================================================================
# Built-in system for providing hints that escalate with attempts
#
# Example step with progressive hints:
#
# - step_id: "difficult_question"
#   question: "What is the capital of Burkina Faso?"
#
#   hints:
#     - attempt: 1
#       text: "💡 Hint: It's not the largest city in the country."
#       counts_as_attempt: false
#
#     - attempt: 2
#       text: "💡 Hint: The name means 'City of Honest People'."
#       counts_as_attempt: false
#
#     - attempt: 3
#       text: "💡 Strong Hint: It starts with 'Oua' and ends with 'dougou'."
#       counts_as_attempt: false
#
#   buckets: [correct, incorrect, need_hint]
#
#   transitions:
#     correct:
#       content_blocks:
#         - "Excellent! Ouagadougou is correct!"
#       next_section_and_step: "next:step"
#
#     incorrect:
#       content_blocks:
#         - "Not quite. Try again!"
#       next_section_and_step: "current:difficult_question"
#
#     need_hint:
#       content_blocks:
#         - "Let me help you..."
#       counts_as_attempt: false
#       next_section_and_step: "current:difficult_question"
#
# Hints auto-display when attempt number matches
# Hints support template variables: "Attempt {{current_attempt}} of {{max_attempts}}"

progressive_hints_example: "See activity-test-v2-features.yaml for working example"

# ==============================================================================
# WEIGHTED RANDOM SELECTION
# ==============================================================================
# Choose random values with different probabilities

# OLD WAY - Equal probability:
metadata_random:
  loot: "sword"    # 33% each
  loot: "dagger"   # 33% each
  loot: "staff"    # 33% each

# NEW WAY - Weighted probabilities:
metadata_weighted_random:
  loot:
    - value: "common_sword"
      weight: 70         # 70% chance
    - value: "rare_dagger"
      weight: 25         # 25% chance
    - value: "legendary_staff"
      weight: 5          # 5% chance

# Weights don't need to sum to 100 - they're relative:
metadata_weighted_random:
  reward:
    - value: "gold"
      weight: 10   # 10/(10+3+1) = 71.4%
    - value: "gem"
      weight: 3    # 3/(10+3+1) = 21.4%
    - value: "artifact"
      weight: 1    # 1/(10+3+1) = 7.1%

# Also works with metadata_tmp_weighted_random for temporary values

# Example: Random encounter
transitions:
  explore_forest:
    metadata_weighted_random:
      encounter:
        - value: "nothing"
          weight: 50       # 50% - No encounter
        - value: "merchant"
          weight: 30       # 30% - Friendly merchant
        - value: "goblin"
          weight: 15       # 15% - Fight goblin
        - value: "treasure"
          weight: 5        # 5% - Find treasure!

    ai_feedback:
      tokens_for_ai: |
        Describe what happens based on metadata.encounter:
        - nothing: Peaceful walk through forest
        - merchant: Meet a traveling merchant
        - goblin: Surprise goblin attack!
        - treasure: Discover hidden treasure chest!

# ==============================================================================
# DYNAMIC QUESTION TEXT
# ==============================================================================
# Questions can now use template variables

# Static question (old way):
question: "What is 2 + 2?"

# Dynamic question with templates (new way):
question: "What is {{metadata.num1}} + {{metadata.num2}}?"

# Example: Math quiz with random numbers
#
# - step_id: "addition"
#   pre_script: |
#     import random
#     result = {
#       "metadata": {
#         "num1": random.randint(1, 10),
#         "num2": random.randint(1, 10)
#       }
#     }
#     return result
#
#   question: "What is {{metadata.num1}} + {{metadata.num2}}?"
#
#   tokens_for_ai: |
#     Calculate the correct answer: {{metadata.num1}} + {{metadata.num2}}
#     Categorize as 'correct' if their answer matches.
#
#   buckets: [correct, incorrect]
#
# More personalized question examples:
# - "{{metadata.character_name}}, what is your quest?"
# - "You have {{metadata.gold}} gold. How much do you spend?"
# - "Round {{current_attempt}}: What's your move?"

dynamic_question_example: "See activity-test-v2-features.yaml for working example"

# ==============================================================================
# BUILT-IN ATTEMPT COUNTER ACCESS
# ==============================================================================
# Access attempt information in templates

# Available variables:
# - {{current_attempt}}      : 1, 2, 3, ... (current attempt number)
# - {{max_attempts}}         : 3 (or custom value from default_max_attempts_per_step)
# - {{attempts_remaining}}   : max_attempts - current_attempt

# Examples:

content_blocks:
  - "Attempt {{current_attempt}} of {{max_attempts}}"
  - "You have {{attempts_remaining}} tries left"

question: "Try {{current_attempt}}: What's your answer?"

ai_feedback:
  tokens_for_ai: |
    This is attempt {{current_attempt}} of {{max_attempts}}.
    They have {{attempts_remaining}} attempts remaining.

    Adjust your feedback based on the attempt number:
    - On their last attempt: Be clear and helpful
    - With 2 attempts left: Provide a gentle hint
    - With more attempts: Encourage them to think carefully

# Conditional content based on attempts:
content_blocks:
  - text: "First try - think carefully!"
    show_if:
      current_attempt: 1

  - text: "Second try - you're getting closer!"
    show_if:
      current_attempt: 2

  - text: "Last chance! Here's a hint..."
    show_if:
      current_attempt: 3

# ==============================================================================
# SESSION PERSISTENCE (Twitch Plays Model)
# ==============================================================================
# How metadata and state persist across users and sessions

# Key Facts:
# ----------
# 1. ONE GAME STATE PER ROOM: All users in a room share the same activity state
# 2. METADATA IS SHARED: When one user updates metadata, all users see it
# 3. DATABASE PERSISTENCE: State survives browser refreshes and reconnections
# 4. ANYONE CAN CONTROL: Any user can provide input to advance the shared game
# 5. LIKE TWITCH PLAYS POKEMON: Collaborative control of single game instance

# Lifecycle:
# ----------
# Activity starts     → State saved to database (room_id, section_id, step_id, metadata)
# User interacts      → Metadata updates, state progresses
# Browser refreshes   → State persists (loaded from database)
# Activity completes  → State deleted from database
# Activity canceled   → State deleted from database

# Use Cases:
# ----------
# - Classroom: Teacher projects, students call out answers collectively
# - Collaboration: Multiple people solve puzzle together
# - Public challenges: Community progresses through shared experience
# - Learning together: Everyone learns from same shared game state

# Implications for Activity Design:
# ----------------------------------
# - Design for SHARED state, not per-player state
# - Metadata represents THE GAME, not individual players
# - Multiple users may answer - first valid response advances
# - Consider: "What if 10 people are playing together?"

# ==============================================================================
# VALIDATION RULES
# ==============================================================================

# REQUIRED:
# ---------
# ✓ Every activity must have "sections" (at least one)
# ✓ Every section needs: section_id, title, steps
# ✓ Every step needs: step_id, title
# ✓ Every step needs EITHER content_blocks OR question (or both)
# ✓ Steps with questions need: buckets, transitions, tokens_for_ai
# ✓ Every bucket must have a corresponding transition
# ✓ All next_section_and_step targets must exist

# FORBIDDEN:
# ----------
# ✗ Terminal steps (no next_section_and_step) CANNOT have questions
# ✗ Section IDs must be unique within activity
# ✗ Step IDs must be unique within section
# ✗ Random bucket names must exist in main buckets list
# ✗ Random bucket probabilities must be 0.0 to 1.0

# WARNINGS:
# ---------
# ⚠ Total random bucket probability > 1.0 (overlapping events)
# ⚠ Circular loops without exit path
# ⚠ Python syntax errors in processing scripts

# ==============================================================================
# BEST PRACTICES
# ==============================================================================

# 1. START SIMPLE
#    - Begin with content-only steps and simple questions
#    - Add complexity incrementally
#    - Test frequently with CLI simulator

# 2. CLEAR INSTRUCTIONS
#    - Write specific tokens_for_ai that explain each bucket clearly
#    - Give examples of what qualifies for each category
#    - Be generous in accepting valid responses

# 3. METADATA STRATEGY
#    - Track meaningful state: score, progress, user choices
#    - Use descriptive key names: "programming_language" not "pl"
#    - Clean up temporary metadata with metadata_tmp_add

# 4. RANDOM EVENTS
#    - Use probabilities that feel right (5-15% for rare events)
#    - Set counts_as_attempt: false for random buckets
#    - Don't override user navigation unless necessary

# 5. FEEDBACK QUALITY
#    - Reference specific parts of user's answer
#    - Provide actionable suggestions for improvement
#    - Celebrate progress and effort

# 6. TERMINATION
#    - Always provide clear path to completion
#    - Mark completion: metadata_add: activity_completed: "true"
#    - Give users a sense of accomplishment

# 7. TESTING
#    - Validate YAML: python activity_yaml_validator.py your_activity.yaml
#    - Test all paths: source vars.sh && python research/guarded_ai.py your_activity.yaml
#    - Try wrong answers, edge cases, language switching

# ==============================================================================
# MODEL CONFIGURATION
# ==============================================================================

# Environment Variables (in vars.sh):
# ------------------------------------
# MODEL_ENDPOINT_1=http://localhost:8080/v1
# MODEL_API_KEY_1=your-api-key
# MODEL_NAME_1=model  # Optional: actual model name for endpoint
#
# MODEL_ENDPOINT_2=http://localhost:8081/v1
# MODEL_API_KEY_2=your-api-key
# MODEL_NAME_2=gpt-4
#
# MODEL_ENDPOINT_3=http://localhost:8082/v1
# MODEL_API_KEY_3=your-api-key
# MODEL_NAME_3=model

# Recommended Models:
# -------------------
# MODEL_1: Hermes-3-Llama-3.1-8B (default, fast, excellent for classification)
# MODEL_2: Larger general model (if available)
# MODEL_3: Qwen3-Coder-30B (for programming activities)

# Model Selection Strategy:
# -------------------------
# - Classifier: Use MODEL_1 (fast 8B model) for instant categorization
# - Feedback: Use specialized model for domain-specific feedback
#   - Programming → MODEL_3 (Qwen3-Coder)
#   - General → MODEL_1 (Hermes)
#   - Advanced reasoning → MODEL_2 (larger model)

# ==============================================================================
# EXAMPLES
# ==============================================================================

# See these reference activities:
# -------------------------------
# activity26-magic-8-ball.yaml           - Looping, randomness, replayability
# activity31-scientific-method.yaml      - Educational scaffolding
# activity37-programming-languages.yaml  - Model overrides, code generation
# activity40-fashion-empire-backrooms.yaml - Random buckets, complex navigation

# ==============================================================================
# END OF SPECIFICATION
# ==============================================================================
