Compare commits
1 commit
main
...
python-exe
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f99508898 |
98
.github/workflows/test.yml
vendored
|
|
@ -1,98 +0,0 @@
|
|||
name: Run Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master, develop, claude/** ]
|
||||
pull_request:
|
||||
branches: [ main, master, develop ]
|
||||
|
||||
# Cancel in-progress runs when a new commit is pushed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.13
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-test.txt
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
pytest tests/unit/ -v --tb=short --cov=. --cov-report=term-missing
|
||||
env:
|
||||
SQLALCHEMY_DATABASE_URI: "sqlite:///:memory:"
|
||||
TESTING: "1"
|
||||
MODEL_ENDPOINT_0: "https://hermes.ai.unturf.com/v1"
|
||||
MODEL_API_KEY_0: "dummy"
|
||||
|
||||
- name: Run functional tests
|
||||
run: |
|
||||
pytest tests/functional/ -v --tb=short
|
||||
env:
|
||||
SQLALCHEMY_DATABASE_URI: "sqlite:///:memory:"
|
||||
TESTING: "1"
|
||||
MODEL_ENDPOINT_0: "https://hermes.ai.unturf.com/v1"
|
||||
MODEL_API_KEY_0: "dummy"
|
||||
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
pytest tests/integration/ -v --tb=short
|
||||
env:
|
||||
SQLALCHEMY_DATABASE_URI: "sqlite:///:memory:"
|
||||
TESTING: "1"
|
||||
MODEL_ENDPOINT_0: "https://hermes.ai.unturf.com/v1"
|
||||
MODEL_API_KEY_0: "dummy"
|
||||
|
||||
- name: Validate activity YAML files
|
||||
run: |
|
||||
python activity_yaml_validator.py research/SPEC.yaml
|
||||
python activity_yaml_validator.py research/activity*.yaml
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.13
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install linting dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install black flake8
|
||||
|
||||
- name: Check code formatting with black
|
||||
run: |
|
||||
black --check --diff --exclude=venv .
|
||||
continue-on-error: true
|
||||
|
||||
- name: Lint with flake8 (syntax errors)
|
||||
run: |
|
||||
# Stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=venv
|
||||
|
||||
- name: Lint with flake8 (style warnings)
|
||||
run: |
|
||||
# Exit-zero treats all errors as warnings
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=venv
|
||||
continue-on-error: true
|
||||
6
.gitignore
vendored
|
|
@ -1,14 +1,8 @@
|
|||
*.swp
|
||||
env
|
||||
venv/
|
||||
instance/
|
||||
__pycache__/
|
||||
.flaskenv
|
||||
.flaskenv-exported
|
||||
.aws-sam/
|
||||
samconfig.toml
|
||||
vars.sh
|
||||
.coverage
|
||||
htmlcov/
|
||||
unturf-debugging.md
|
||||
research/tmp*.yaml
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
# GitLab CI/CD Pipeline for OpenCompletion
|
||||
# Uses shell executor on build-tagged runners
|
||||
|
||||
stages:
|
||||
- test
|
||||
- lint
|
||||
|
||||
variables:
|
||||
SQLALCHEMY_DATABASE_URI: "sqlite:///:memory:"
|
||||
TESTING: "1"
|
||||
MODEL_ENDPOINT_0: "https://hermes.ai.unturf.com/v1"
|
||||
MODEL_API_KEY_0: "dummy"
|
||||
|
||||
# Template for Python setup (shell executor)
|
||||
.python_setup:
|
||||
tags:
|
||||
- build
|
||||
before_script:
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- python3 -m pip install --upgrade pip
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements-test.txt
|
||||
|
||||
# Unit Tests
|
||||
unit_tests:
|
||||
extends: .python_setup
|
||||
stage: test
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- pytest tests/unit/ -v --tb=short --cov=. --cov-report=term-missing
|
||||
|
||||
# Functional Tests
|
||||
functional_tests:
|
||||
extends: .python_setup
|
||||
stage: test
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- pytest tests/functional/ -v --tb=short
|
||||
|
||||
# Integration Tests
|
||||
integration_tests:
|
||||
extends: .python_setup
|
||||
stage: test
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- pytest tests/integration/ -v --tb=short
|
||||
|
||||
# Validate Activity YAML Files
|
||||
validate_yaml:
|
||||
extends: .python_setup
|
||||
stage: test
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- python activity_yaml_validator.py research/SPEC.yaml
|
||||
- python activity_yaml_validator.py research/activity*.yaml
|
||||
|
||||
# Lint - Syntax Errors (blocking)
|
||||
lint_syntax:
|
||||
stage: lint
|
||||
tags:
|
||||
- build
|
||||
before_script:
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip install flake8
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=venv
|
||||
|
||||
# Lint - Style Warnings (non-blocking)
|
||||
lint_style:
|
||||
stage: lint
|
||||
tags:
|
||||
- build
|
||||
before_script:
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip install black flake8
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- black --check --diff --exclude=venv . || true
|
||||
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=venv
|
||||
allow_failure: true
|
||||
282
Makefile
|
|
@ -1,282 +0,0 @@
|
|||
# Makefile for OpenCompletion Testing Framework
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "OpenCompletion Testing Framework"
|
||||
@echo "================================"
|
||||
@echo ""
|
||||
@echo "🧪 Test Commands:"
|
||||
@echo " test - Run all tests (unit, integration, functional)"
|
||||
@echo " test-unit - Run only unit tests"
|
||||
@echo " test-integration - Run only integration tests"
|
||||
@echo " test-functional - Run only functional tests"
|
||||
@echo " test-validator - Run YAML validator tests"
|
||||
@echo " test-yaml-loading - Run YAML loading/parsing tests"
|
||||
@echo " test-activity-flows - Run activity flow tests"
|
||||
@echo " test-battleship - Run battleship game tests"
|
||||
@echo " test-guarded-ai - Run guarded_ai.py functionality tests"
|
||||
@echo " test-multiple-files - Run integration tests across all activity files"
|
||||
@echo ""
|
||||
@echo "📋 Validation Commands:"
|
||||
@echo " validate-yaml - Validate all YAML files in research/"
|
||||
@echo ""
|
||||
@echo "🛠️ Development Commands:"
|
||||
@echo " venv - Create virtual environment and install dependencies"
|
||||
@echo " dev-setup - Install development dependencies"
|
||||
@echo " lint - Run code linting and formatting"
|
||||
@echo " clean - Clean up generated files"
|
||||
@echo " clean-all - Remove virtual environment"
|
||||
|
||||
# Setup virtual environment
|
||||
.PHONY: venv
|
||||
venv:
|
||||
@if [ ! -d "venv" ]; then \
|
||||
echo "🚀 Creating virtual environment..."; \
|
||||
python3 -m venv venv; \
|
||||
echo "📦 Installing basic dependencies..."; \
|
||||
venv/bin/pip install --upgrade pip; \
|
||||
venv/bin/pip install -r requirements.txt || echo "⚠️ Failed to install basic dependencies"; \
|
||||
echo "✅ Virtual environment ready!"; \
|
||||
else \
|
||||
echo "✅ Virtual environment already exists"; \
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# MAIN TEST COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Run all tests
|
||||
.PHONY: test
|
||||
test: test-unit test-integration test-functional test-validator test-yaml-loading test-activity-flows test-battleship test-guarded-ai test-multiple-files validate-yaml
|
||||
@echo ""
|
||||
@echo "🎉 All tests completed!"
|
||||
@echo "📊 Test Summary:"
|
||||
@echo " ✅ Unit tests - Core functionality"
|
||||
@echo " ✅ Integration tests - Cross-component testing"
|
||||
@echo " ✅ Functional tests - End-to-end workflows"
|
||||
@echo " ✅ YAML validation - All activity files"
|
||||
@echo " ✅ All specific test targets completed"
|
||||
|
||||
# Run unit tests only
|
||||
.PHONY: test-unit
|
||||
test-unit: venv
|
||||
@echo "🔬 Running unit tests..."
|
||||
@if command -v pytest >/dev/null 2>&1; then \
|
||||
python -m pytest tests/unit/ -v --tb=short; \
|
||||
else \
|
||||
echo "📝 Running unit tests directly..."; \
|
||||
python tests/unit/test_yaml_loading.py; \
|
||||
python tests/unit/test_activity_yaml_validator.py; \
|
||||
fi
|
||||
|
||||
# Run integration tests only
|
||||
.PHONY: test-integration
|
||||
test-integration: venv
|
||||
@echo "🔗 Running integration tests..."
|
||||
@if command -v pytest >/dev/null 2>&1; then \
|
||||
python -m pytest tests/integration/ -v --tb=short; \
|
||||
else \
|
||||
echo "📝 Running integration tests directly..."; \
|
||||
python tests/integration/test_multiple_activities.py; \
|
||||
fi
|
||||
|
||||
# Run functional tests only
|
||||
.PHONY: test-functional
|
||||
test-functional: venv
|
||||
@echo "⚡ Running functional tests..."
|
||||
@if command -v pytest >/dev/null 2>&1; then \
|
||||
python -m pytest tests/functional/ -v --tb=short; \
|
||||
else \
|
||||
echo "📝 Running functional tests directly..."; \
|
||||
python tests/functional/test_activity_flows.py; \
|
||||
python tests/functional/test_battleship_pre_script.py; \
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# SPECIFIC TEST COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Run YAML validator tests only
|
||||
.PHONY: test-validator
|
||||
test-validator: venv
|
||||
@echo "📋 Running YAML validator tests..."
|
||||
python tests/unit/test_activity_yaml_validator.py
|
||||
|
||||
# Run YAML loading tests only
|
||||
.PHONY: test-yaml-loading
|
||||
test-yaml-loading: venv
|
||||
@echo "📄 Running YAML loading/parsing tests..."
|
||||
python tests/unit/test_yaml_loading.py
|
||||
|
||||
# Run activity flow tests
|
||||
.PHONY: test-activity-flows
|
||||
test-activity-flows: venv
|
||||
@echo "🔄 Running activity flow tests..."
|
||||
python tests/functional/test_activity_flows.py
|
||||
|
||||
# Run battleship game tests
|
||||
.PHONY: test-battleship
|
||||
test-battleship: venv
|
||||
@echo "🚢 Running battleship game tests..."
|
||||
python tests/functional/test_battleship_pre_script.py
|
||||
|
||||
# Run guarded_ai functionality tests
|
||||
.PHONY: test-guarded-ai
|
||||
test-guarded-ai: venv
|
||||
@echo "🛡️ Running guarded_ai.py functionality tests..."
|
||||
python tests/integration/test_regression_fixes.py
|
||||
|
||||
# Run integration tests across all activity files
|
||||
.PHONY: test-multiple-files
|
||||
test-multiple-files: venv
|
||||
@echo "📁 Running integration tests across all activity files..."
|
||||
python tests/integration/test_multiple_activities.py
|
||||
|
||||
# ============================================================================
|
||||
# VALIDATION COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Validate all YAML files
|
||||
.PHONY: validate-yaml
|
||||
validate-yaml: venv
|
||||
@echo "📋 Validating all YAML files..."
|
||||
python activity_yaml_validator.py research/*.yaml
|
||||
|
||||
# ============================================================================
|
||||
# DEVELOPMENT AND CI/CD COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Run tests with coverage (requires pytest and coverage)
|
||||
.PHONY: test-cov
|
||||
test-cov: dev-setup
|
||||
@echo "📊 Running tests with coverage..."
|
||||
venv/bin/pip install pytest-cov
|
||||
venv/bin/python -m pytest tests/ --cov=. --cov-report=html --cov-report=term-missing -v
|
||||
|
||||
|
||||
# Format and lint code
|
||||
.PHONY: format
|
||||
format: dev-setup
|
||||
@echo "🎨 Formatting code..."
|
||||
venv/bin/black .
|
||||
venv/bin/isort .
|
||||
|
||||
.PHONY: lint
|
||||
lint: dev-setup
|
||||
@echo "🔍 Linting code..."
|
||||
venv/bin/black --check .
|
||||
venv/bin/isort --check-only .
|
||||
venv/bin/flake8 .
|
||||
# Install development dependencies
|
||||
.PHONY: dev-setup
|
||||
dev-setup: venv
|
||||
@echo "🛠️ Installing development dependencies..."
|
||||
venv/bin/pip install black flake8 isort pytest coverage
|
||||
@echo "✅ Development environment ready!"
|
||||
|
||||
# ============================================================================
|
||||
# CI/CD AND AUTOMATION COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Full CI pipeline
|
||||
.PHONY: ci
|
||||
ci: clean test validate-yaml lint
|
||||
@echo ""
|
||||
@echo "🎯 CI Pipeline Results:"
|
||||
@echo " ✅ Tests passed"
|
||||
@echo " ✅ YAML validation passed"
|
||||
@echo " ✅ Code linting completed"
|
||||
@echo "🚀 Ready for deployment!"
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# UTILITY COMMANDS
|
||||
# ============================================================================
|
||||
|
||||
# Clean generated files
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@echo "🧹 Cleaning generated files..."
|
||||
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -name "*.pyc" -delete 2>/dev/null || true
|
||||
find . -name "*.pyo" -delete 2>/dev/null || true
|
||||
find . -name "*~" -delete 2>/dev/null || true
|
||||
|
||||
.PHONY: init-db
|
||||
init-db:
|
||||
@echo "🗄️ Initializing database tables..."
|
||||
@if [ -f vars.sh ]; then \
|
||||
. ./vars.sh && python init_db.py; \
|
||||
echo "✅ Database tables created successfully"; \
|
||||
else \
|
||||
echo "❌ Error: vars.sh not found. Please create it from vars.sh.sample"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
clean-cache:
|
||||
rm -rf .pytest_cache/ 2>/dev/null || true
|
||||
rm -rf htmlcov/ 2>/dev/null || true
|
||||
rm -rf .coverage 2>/dev/null || true
|
||||
rm -rf *.tmp 2>/dev/null || true
|
||||
|
||||
# Remove virtual environment
|
||||
.PHONY: clean-all
|
||||
clean-all: clean
|
||||
@echo "💣 Removing virtual environment..."
|
||||
rm -rf venv
|
||||
|
||||
# Show test structure
|
||||
.PHONY: test-info
|
||||
test-info:
|
||||
@echo "📁 Test Structure:"
|
||||
@echo " tests/"
|
||||
@echo " ├── unit/ - Unit tests for individual components"
|
||||
@echo " │ ├── test_yaml_loading.py - YAML loading/parsing tests"
|
||||
@echo " │ └── test_activity_yaml_validator.py - Validator functionality tests"
|
||||
@echo " ├── integration/ - Integration tests across components"
|
||||
@echo " │ ├── test_multiple_activities.py - Tests across all activity files"
|
||||
@echo " │ └── test_regression_fixes.py - Regression and fix validation"
|
||||
@echo " └── functional/ - End-to-end functional tests"
|
||||
@echo " ├── test_activity_flows.py - Complete activity workflows"
|
||||
@echo " └── test_battleship_pre_script.py - Battleship game functionality"
|
||||
@echo ""
|
||||
@echo "🎯 Key Test Commands:"
|
||||
@echo " make test - Run all tests"
|
||||
@echo " make validate-yaml - Validate all YAML files"
|
||||
# ============================================================================
|
||||
# CODE EXECUTOR API TESTING
|
||||
# ============================================================================
|
||||
|
||||
# Test artifact retrieval - compile C code, get base64 binary, decode and test execution
|
||||
# URL can be overridden: make test-artifact URL=https://code.ai.unturf.com
|
||||
.PHONY: test-artifact
|
||||
test-artifact:
|
||||
$(eval URL ?= http://127.0.0.1:8080)
|
||||
@echo "=========================================="
|
||||
@echo "Testing Binary Artifact Retrieval"
|
||||
@echo "=========================================="
|
||||
@echo "API: $(URL)"
|
||||
@echo ""
|
||||
@echo "Step 1: Compiling C code and retrieving base64 binary..."
|
||||
@curl -s -X POST $(URL)/execute \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"language": "c", "code": "#include <stdio.h>\nint main() { printf(\"Hello from artifact!\\n\"); return 0; }", "return_artifact": true}' \
|
||||
| jq -r '.stdout.artifact.data' > /tmp/artifact.b64
|
||||
@echo "✓ Base64 artifact saved to /tmp/artifact.b64"
|
||||
@echo " Size: $$(wc -c < /tmp/artifact.b64) bytes (base64)"
|
||||
@echo ""
|
||||
@echo "Step 2: Decoding base64 to binary..."
|
||||
@base64 -d /tmp/artifact.b64 > /tmp/artifact_binary
|
||||
@chmod +x /tmp/artifact_binary
|
||||
@echo "✓ Binary decoded to /tmp/artifact_binary"
|
||||
@echo " Size: $$(wc -c < /tmp/artifact_binary) bytes (ELF binary)"
|
||||
@echo ""
|
||||
@echo "Step 3: Verifying ELF binary..."
|
||||
@file /tmp/artifact_binary
|
||||
@echo ""
|
||||
@echo "Step 4: Executing binary..."
|
||||
@/tmp/artifact_binary
|
||||
@echo ""
|
||||
@echo "✓ Artifact test complete!"
|
||||
@echo ""
|
||||
@echo "Cleanup: rm /tmp/artifact.b64 /tmp/artifact_binary"
|
||||
164
README.rst
|
|
@ -1,27 +1,28 @@
|
|||
Open Completion
|
||||
flask-socketio-llm-completions
|
||||
========================================
|
||||
|
||||
* repo: `opencompletion.com <https://opencompletion.com>`_
|
||||
This project is a chatroom application that allows users to join different chat rooms, send messages, and interact with multiple language models in real-time. The backend is built with Flask and Flask-SocketIO for real-time web communication, while the frontend uses HTML, CSS, and JavaScript to provide an interactive user interface.
|
||||
|
||||
* demo: `demo.opencompletion.com <https://demo.opencompletion.com>`_
|
||||
.. image:: flask-socketio-llm-completions.png
|
||||
:alt: Flask-SocketIO LLM Completions
|
||||
:align: center
|
||||
|
||||
.. image:: flask-socketio-llm-completions-2.png
|
||||
:alt: Flask-SocketIO LLM Completions Dall-e-3
|
||||
:align: center
|
||||
|
||||
Chatroom applicationallows users to join rooms, send messages, & interact with multiple language models in real-time. Backend written with Flask & Flask-SocketIO for real-time web socket streaming. Frontend uses minimal HTML, CSS, & JavaScript to provide an interactive user interface.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Real-time messaging between users in a chatroom.
|
||||
- Ability to join different chatrooms with unique URLs.
|
||||
- Integration with language models for generating room titles and processing messages.
|
||||
- Integration with OpenAI's language models for generating room titles and processing messages.
|
||||
- Syntax highlighting for code blocks within messages.
|
||||
- Markdown rendering for messages.
|
||||
- **Code execution**: Run code blocks directly in the browser with support for 38+ programming languages.
|
||||
- **Text-to-speech**: Convert AI responses to speech with multiple voice options.
|
||||
- Commands to load and save code blocks to AWS S3.
|
||||
- Database storage for messages and chatrooms using SQLAlchemy.
|
||||
- Migration support with Flask-Migrate.
|
||||
- Email OTP authentication with private room support
|
||||
- Room forking, archiving, and owner management
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
|
@ -33,7 +34,8 @@ Requirements
|
|||
- Flask-Migrate
|
||||
- eventlet or gevent
|
||||
- boto3 (for interacting with AWS Bedrock currently Claude, and S3 access)
|
||||
- OpenAI client (for interacting with vLLM & Ollama inference servers)
|
||||
- openai (for interacting with OpenAI's language models)
|
||||
- mistralai (for interacting with MistralAI's language models)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
|
@ -42,25 +44,27 @@ To set up the project, follow these steps:
|
|||
|
||||
1. Clone this repository::
|
||||
|
||||
git clone https://github.com/russellballestrini/opencompletion.git
|
||||
cd opencompletion
|
||||
|
||||
**Git Remotes**: This repo is configured to push to both GitHub and unturf simultaneously.
|
||||
The ``origin`` remote has two push URLs:
|
||||
|
||||
- GitHub: ``git@github.com:russellballestrini/opencompletion.git``
|
||||
- unturf: ``ssh://git@git.unturf.com:2222/engineering/unturf/opencompletion.com.git``
|
||||
git clone https://github.com/russellballestrini/flask-socketio-llm-completions.git
|
||||
cd flask-socketio-llm-completions
|
||||
|
||||
2. Create a virtual environment and activate it::
|
||||
|
||||
python3 -m venv env
|
||||
python3 -m venv ven
|
||||
source env/bin/activate # On Windows use `env\Scripts\activate`
|
||||
|
||||
3. Install the required dependencies::
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
4. Initialize the database:
|
||||
4. Set up environment variables for your AWS credentials and OpenAI API key::
|
||||
|
||||
export AWS_ACCESS_KEY_ID="your_access_key"
|
||||
export AWS_SECRET_ACCESS_KEY="your_secret_key"
|
||||
export S3_BUCKET_NAME="your_s3_bucket_name"
|
||||
export OPENAI_API_KEY="your_openai_api_key"
|
||||
export MISTRAL_API_KEY="your_mistralai_api_key"
|
||||
|
||||
5. Initialize the database:
|
||||
|
||||
Before running the application for the first time, you need to create the database and tables, and then stamp the Alembic migrations to mark them as up to date. Follow these steps::
|
||||
|
||||
|
|
@ -70,43 +74,11 @@ To set up the project, follow these steps:
|
|||
Usage
|
||||
-----
|
||||
|
||||
Set up environment variables for your AWS, OpenAI, MistralAI, together.ai, grok, groq, google, API keys.
|
||||
|
||||
* make a copy of ``vars.sh.sample`` and fill in your API keys!
|
||||
|
||||
Other env vars::
|
||||
|
||||
export AWS_ACCESS_KEY_ID="your_access_key"
|
||||
export AWS_SECRET_ACCESS_KEY="your_secret_key"
|
||||
export S3_BUCKET_NAME="your_s3_bucket_name"
|
||||
|
||||
Here are some free endpoint for research only!::
|
||||
|
||||
export MODEL_ENDPOINT_1=https://hermes.ai.unturf.com/v1
|
||||
export MODEL_ENDPOINT_2=https://qwen.ai.unturf.com/v1
|
||||
export MODEL_ENDPOINT_3=https://gpt-oss.ai.unturf.com/v1
|
||||
|
||||
Optional SMTP for email OTP authentication::
|
||||
|
||||
export SMTP_HOST=smtp.gmail.com
|
||||
export SMTP_PORT=587
|
||||
export SMTP_USER=your@email.com
|
||||
export SMTP_PASSWORD=your_app_password
|
||||
|
||||
To start the application with socket.io run::
|
||||
|
||||
python app.py
|
||||
|
||||
Optionally flags ``python app.py --local-activities --profile <aws-profile-name>``::
|
||||
|
||||
usage: app.py [-h] [--profile PROFILE] [--local-activities] [--port PORT]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--profile PROFILE AWS profile name
|
||||
--local-activities Use local activity files instead of S3
|
||||
--port PORT Port number (default: 5001)
|
||||
|
||||
Optionally pass ``python app.py --profile <aws-profile-name>``
|
||||
|
||||
The application will be available at ``http://127.0.0.1:5001`` by default.
|
||||
|
||||
|
|
@ -114,24 +86,40 @@ The application will be available at ``http://127.0.0.1:5001`` by default.
|
|||
Interacting with Language Models
|
||||
--------------------------------
|
||||
|
||||
To interact with the various language models, choose from the drop down and send a message!
|
||||
To interact with the various language models, you can use the following commands within the chat:
|
||||
|
||||
- For GPT-3, send a message with ``gpt-3`` and include your prompt.
|
||||
- For GPT-4, send a message with ``gpt-4`` and include your prompt.
|
||||
- For Claude-v1, send a message with ``claude-v1`` and include your prompt.
|
||||
- For Claude-v2, send a message with ``claude-v2`` and include your prompt.
|
||||
- For Mistral-tiny, send a message with ``mistral`` and include your prompt.
|
||||
- For Dall-e-3, send a message with ``dall-e-3`` and include your prompt.
|
||||
|
||||
The system will process your message and provide a response from the selected language model.
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
The chatrooms support some special commands:
|
||||
The application supports special commands for interacting with the chatroom:
|
||||
|
||||
- ``/s3 load <file_path>``: Loads a file from S3 and displays its content in the chatroom.
|
||||
- ``/s3 save <file_path>``: Saves the most recent code block from the chatroom to S3.
|
||||
- ``/s3 ls <file_s3_path_pattern>``: Lists files from S3 that match the given pattern. Use ``*`` to list all files.
|
||||
- ``/title new``: Generates a new title which reflects conversation content for the current chatroom using gpt-4.
|
||||
- ``/cancel``: Cancel the most recent chat completion from streaming into the chatroom.
|
||||
- ``/help``: Displays the list of commands and models to choose from.
|
||||
- ``/python``: Executes the most recent Python code block sent in the chatroom and returns the output or any errors.
|
||||
|
||||
Code Execution
|
||||
--------------
|
||||
---
|
||||
|
||||
Code blocks can be executed directly in the browser using the "▶ Run" button. Supports 30+ programming languages with automatic language detection. Code runs in isolated, self-terminating sandbox containers. Compiled binaries can be downloaded directly from the interface.
|
||||
The ``/s3 ls`` command can be used to list files in the connected S3 bucket. You can specify a pattern to filter the files listed. For example:
|
||||
|
||||
- ``/s3 ls *`` will list all files in the bucket.
|
||||
- ``/s3 ls *.py`` will list all Python files.
|
||||
- ``/s3 ls README.*`` will list files starting with "README." and any extension.
|
||||
|
||||
- ``/python``: Executes the most recent Python code block sent in the chatroom and returns the output or any errors. This command allows users to run Python code snippets in real-time and is useful for quick debugging, learning, or collaborative coding sessions. Use this command with caution, as executing arbitrary code can pose security risks.
|
||||
|
||||
Please note that the ``/python`` command should be used responsibly and with consideration of the security implications of executing arbitrary code. It is recommended to implement additional security measures if this command is to be used in a production environment.
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
|
@ -140,71 +128,13 @@ Structure
|
|||
- ``chat.html``: The HTML template for the chatroom interface.
|
||||
- ``static/``: Directory for static files like CSS, JavaScript, and images.
|
||||
- ``templates/``: Directory for HTML templates.
|
||||
- ``research/``: Guarded AI activities or processes. Example YAMLs.
|
||||
|
||||
|
||||
Activity Mode
|
||||
--------------
|
||||
|
||||
Activity mode is an interactive experience where users can engage with a guided AI to learn and answer questions.
|
||||
|
||||
The AI provides feedback based on the user's responses and guides them through different sections and steps of an activity.
|
||||
|
||||
This mode is designed to be on the "rails", educational, & engaging.
|
||||
|
||||
The server expects to load the YAML file out of the S3 bucket you specify in your environment variables.
|
||||
|
||||
1. **Start an Activity**: Use the ``/activity`` command followed by the object path to the activity YAML file to start a new activity.
|
||||
|
||||
``/activity path-to-activity.yaml``
|
||||
|
||||
2. **Display Activity Info**: Use the ``/activity info`` command to display AI information about the current activity, including grading and user performance.
|
||||
|
||||
``/activity info``
|
||||
|
||||
3. **Display Activity Metadata**: Use the ``/activity metadata`` command to display metadata information collected about the activity.
|
||||
|
||||
``/activity metadata``
|
||||
|
||||
4. **Cancel an Activity**: Use the ``/activity cancel`` command to display cancel the current activity running in the room.
|
||||
|
||||
``/activity cancel``
|
||||
|
||||
|
||||
5. **Battleship example**:
|
||||
|
||||
``/activity research/activity29-battleship.yaml``
|
||||
|
||||
.. image:: flask-socketio-llm-completions-battleship.png
|
||||
:align: center
|
||||
|
||||
|
||||
|
||||
Ollama versus vLLM
|
||||
-----------------------------
|
||||
|
||||
We prefer operating an ``vllm`` inference server but some models are packaged exclusively for ``ollama`` so here is an example::
|
||||
|
||||
ollama run hf.co/NousResearch/Hermes-3-Llama-3.1-8B-GGUF:Q8_0
|
||||
|
||||
then::
|
||||
|
||||
export MODEL_ENDPOINT_1=https://localhost:11434/v1
|
||||
|
||||
Then in the app you should be able to talk to ``NousResearch/Hermes-3-Llama-3.1-8B-GGUF:Q8_0``
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Contributions to this project are welcome. Please follow the standard fork and pull request workflow.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This project is public domain. It is free for use and distribution without any restrictions.
|
||||
|
||||
|
||||
.. figure:: https://api.star-history.com/svg?repos=russellballestrini/opencompletion&type=Date
|
||||
:alt: Star History Chart
|
||||
|
|
|
|||
1675
activity.py
|
|
@ -1,354 +0,0 @@
|
|||
"""
|
||||
Utility functions for OpenCompletion Activity System v2.0
|
||||
|
||||
Features:
|
||||
- Template variable rendering ({{metadata.key}}, {{current_attempt}}, etc.)
|
||||
- Advanced metadata conditions (gte, lt, contains, regex, etc.)
|
||||
- Conditional content blocks (show_if)
|
||||
- Conditional navigation (if/elif/else)
|
||||
- Weighted random selection
|
||||
- Progressive hints
|
||||
"""
|
||||
|
||||
import re
|
||||
import random
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
|
||||
def render_template(text: str, context: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Render template variables in text using {{variable}} syntax.
|
||||
|
||||
Supports:
|
||||
- {{metadata.key}} - Access metadata values
|
||||
- {{current_attempt}} - Current attempt number
|
||||
- {{max_attempts}} - Maximum attempts
|
||||
- {{attempts_remaining}} - Remaining attempts
|
||||
- {{current_section}} - Current section ID
|
||||
- {{current_step}} - Current step ID
|
||||
- {{username}} - Last responding username
|
||||
|
||||
Args:
|
||||
text: Text containing {{variable}} templates
|
||||
context: Dictionary with metadata, attempts, section/step info
|
||||
|
||||
Returns:
|
||||
Text with variables replaced
|
||||
"""
|
||||
if not isinstance(text, str):
|
||||
return text
|
||||
|
||||
# Find all {{variable}} patterns
|
||||
pattern = r"\{\{([^}]+)\}\}"
|
||||
|
||||
def replace_variable(match):
|
||||
var_name = match.group(1).strip()
|
||||
|
||||
# Handle metadata.key syntax
|
||||
if var_name.startswith("metadata."):
|
||||
key = var_name[9:] # Remove 'metadata.' prefix
|
||||
metadata = context.get("metadata", {})
|
||||
value = metadata.get(
|
||||
key, f"{{{{metadata.{key}}}}}"
|
||||
) # Keep original if not found
|
||||
return str(value) if value is not None else ""
|
||||
|
||||
# Handle built-in variables
|
||||
value = context.get(
|
||||
var_name, f"{{{{{var_name}}}}}"
|
||||
) # Keep original if not found
|
||||
return str(value) if value is not None else ""
|
||||
|
||||
return re.sub(pattern, replace_variable, text)
|
||||
|
||||
|
||||
def evaluate_condition(
|
||||
metadata: Dict[str, Any], condition_key: str, condition_value: Any
|
||||
) -> bool:
|
||||
"""
|
||||
Evaluate a single condition against metadata.
|
||||
|
||||
Supports operators:
|
||||
- key: value - Equality
|
||||
- key_ne: value - Not equal
|
||||
- key_gt: value - Greater than
|
||||
- key_gte: value - Greater than or equal
|
||||
- key_lt: value - Less than
|
||||
- key_lte: value - Less than or equal
|
||||
- key_between: [min, max] - Between (inclusive)
|
||||
- key_contains: value - Comma-separated list contains value
|
||||
- key_not_contains: value - List does NOT contain value
|
||||
- key_matches: pattern - Regex match
|
||||
- key_exists: true/false - Key existence check
|
||||
- key_not_exists: true/false - Key non-existence check
|
||||
|
||||
Args:
|
||||
metadata: Metadata dictionary to check
|
||||
condition_key: Condition key (may have operator suffix)
|
||||
condition_value: Expected value
|
||||
|
||||
Returns:
|
||||
True if condition met, False otherwise
|
||||
"""
|
||||
# Check for operator suffixes
|
||||
if condition_key.endswith("_ne"):
|
||||
key = condition_key[:-3]
|
||||
return metadata.get(key) != condition_value
|
||||
|
||||
elif condition_key.endswith("_gt"):
|
||||
key = condition_key[:-3]
|
||||
try:
|
||||
return float(metadata.get(key, 0)) > float(condition_value)
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_gte"):
|
||||
key = condition_key[:-4]
|
||||
try:
|
||||
return float(metadata.get(key, 0)) >= float(condition_value)
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_lt"):
|
||||
key = condition_key[:-3]
|
||||
try:
|
||||
return float(metadata.get(key, 0)) < float(condition_value)
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_lte"):
|
||||
key = condition_key[:-4]
|
||||
try:
|
||||
return float(metadata.get(key, 0)) <= float(condition_value)
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_between"):
|
||||
key = condition_key[:-8]
|
||||
if not isinstance(condition_value, list) or len(condition_value) != 2:
|
||||
return False
|
||||
try:
|
||||
val = float(metadata.get(key, 0))
|
||||
return float(condition_value[0]) <= val <= float(condition_value[1])
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_not_contains"):
|
||||
key = condition_key[:-13]
|
||||
value_str = str(metadata.get(key, ""))
|
||||
items = [item.strip() for item in value_str.split(",") if item.strip()]
|
||||
return str(condition_value) not in items
|
||||
|
||||
elif condition_key.endswith("_contains"):
|
||||
key = condition_key[:-9]
|
||||
value_str = str(metadata.get(key, ""))
|
||||
# Split by comma and check if condition_value is in list
|
||||
items = [item.strip() for item in value_str.split(",") if item.strip()]
|
||||
return str(condition_value) in items
|
||||
|
||||
elif condition_key.endswith("_matches"):
|
||||
key = condition_key[:-8]
|
||||
value_str = str(metadata.get(key, ""))
|
||||
try:
|
||||
return bool(re.search(str(condition_value), value_str))
|
||||
except re.error:
|
||||
return False
|
||||
|
||||
elif condition_key.endswith("_not_exists"):
|
||||
key = condition_key[:-11]
|
||||
if condition_value:
|
||||
return key not in metadata
|
||||
else:
|
||||
return key in metadata
|
||||
|
||||
elif condition_key.endswith("_exists"):
|
||||
key = condition_key[:-7]
|
||||
if condition_value:
|
||||
return key in metadata
|
||||
else:
|
||||
return key not in metadata
|
||||
|
||||
else:
|
||||
# Simple equality check
|
||||
return metadata.get(condition_key) == condition_value
|
||||
|
||||
|
||||
def check_conditions(metadata: Dict[str, Any], conditions: Dict[str, Any]) -> bool:
|
||||
"""
|
||||
Check if ALL conditions are met (AND logic).
|
||||
|
||||
Args:
|
||||
metadata: Metadata dictionary
|
||||
conditions: Dictionary of condition_key: condition_value pairs
|
||||
|
||||
Returns:
|
||||
True if all conditions met, False otherwise
|
||||
"""
|
||||
if not conditions:
|
||||
return True
|
||||
|
||||
return all(
|
||||
evaluate_condition(metadata, key, value) for key, value in conditions.items()
|
||||
)
|
||||
|
||||
|
||||
def filter_content_blocks(
|
||||
content_blocks: List[Union[str, Dict[str, Any]]],
|
||||
metadata: Dict[str, Any],
|
||||
context: Dict[str, Any],
|
||||
) -> List[str]:
|
||||
"""
|
||||
Filter and render content blocks based on show_if conditions.
|
||||
|
||||
Content blocks can be:
|
||||
- Simple strings: Always shown
|
||||
- Objects with 'text' and 'show_if': Conditionally shown
|
||||
|
||||
Args:
|
||||
content_blocks: List of content blocks (strings or dicts)
|
||||
metadata: Metadata dictionary for condition evaluation
|
||||
context: Template rendering context
|
||||
|
||||
Returns:
|
||||
List of rendered text strings that passed conditions
|
||||
"""
|
||||
result = []
|
||||
|
||||
for block in content_blocks:
|
||||
if isinstance(block, str):
|
||||
# Simple string - always show, just render templates
|
||||
rendered = render_template(block, context)
|
||||
result.append(rendered)
|
||||
|
||||
elif isinstance(block, dict):
|
||||
# Conditional block - check show_if condition
|
||||
text = block.get("text", "")
|
||||
show_if = block.get("show_if", {})
|
||||
|
||||
# Check if conditions are met
|
||||
if check_conditions(metadata, show_if):
|
||||
rendered = render_template(text, context)
|
||||
result.append(rendered)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def resolve_conditional_navigation(
|
||||
next_section_and_step: Union[str, List[Dict[str, Any]]], metadata: Dict[str, Any]
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Resolve conditional navigation (if/elif/else structure).
|
||||
|
||||
Args:
|
||||
next_section_and_step: Either a string or list of conditional branches
|
||||
metadata: Metadata dictionary for condition evaluation
|
||||
|
||||
Returns:
|
||||
Resolved "section:step" string or None
|
||||
"""
|
||||
# Simple string - return as-is
|
||||
if isinstance(next_section_and_step, str):
|
||||
return next_section_and_step
|
||||
|
||||
# Conditional branches
|
||||
if isinstance(next_section_and_step, list):
|
||||
for branch in next_section_and_step:
|
||||
if "if" in branch:
|
||||
# if branch
|
||||
if check_conditions(metadata, branch["if"]):
|
||||
return branch.get("goto")
|
||||
|
||||
elif "elif" in branch:
|
||||
# elif branch
|
||||
if check_conditions(metadata, branch["elif"]):
|
||||
return branch.get("goto")
|
||||
|
||||
elif "else" in branch:
|
||||
# else branch - always taken if reached
|
||||
return branch.get("goto")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def select_weighted_random(weighted_options: List[Dict[str, Any]]) -> Any:
|
||||
"""
|
||||
Select a random value from weighted options.
|
||||
|
||||
Args:
|
||||
weighted_options: List of dicts with 'value' and 'weight' keys
|
||||
|
||||
Returns:
|
||||
Selected value
|
||||
"""
|
||||
if not weighted_options:
|
||||
return None
|
||||
|
||||
# Extract values and weights
|
||||
values = [opt["value"] for opt in weighted_options]
|
||||
weights = [opt.get("weight", 1) for opt in weighted_options]
|
||||
|
||||
# Use random.choices for weighted selection
|
||||
selected = random.choices(values, weights=weights, k=1)
|
||||
return selected[0]
|
||||
|
||||
|
||||
def get_progressive_hint(
|
||||
hints: List[Dict[str, Any]], current_attempt: int, context: Dict[str, Any]
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Get the hint for the current attempt number, if one exists.
|
||||
|
||||
Args:
|
||||
hints: List of hint dicts with 'attempt', 'text', 'counts_as_attempt' keys
|
||||
current_attempt: Current attempt number (1, 2, 3, ...)
|
||||
context: Template rendering context
|
||||
|
||||
Returns:
|
||||
Hint dict with rendered text, or None if no hint for this attempt
|
||||
"""
|
||||
if not hints:
|
||||
return None
|
||||
|
||||
for hint in hints:
|
||||
if hint.get("attempt") == current_attempt:
|
||||
# Render template variables in hint text
|
||||
hint_text = render_template(hint.get("text", ""), context)
|
||||
return {
|
||||
"text": hint_text,
|
||||
"counts_as_attempt": hint.get("counts_as_attempt", False),
|
||||
}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def create_template_context(
|
||||
metadata: Dict[str, Any],
|
||||
current_attempt: int,
|
||||
max_attempts: int,
|
||||
current_section: str,
|
||||
current_step: str,
|
||||
username: str = "User",
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Create a template rendering context with all built-in variables.
|
||||
|
||||
Args:
|
||||
metadata: Activity metadata
|
||||
current_attempt: Current attempt number
|
||||
max_attempts: Maximum attempts allowed
|
||||
current_section: Current section ID
|
||||
current_step: Current step ID
|
||||
username: Username of last responder
|
||||
|
||||
Returns:
|
||||
Context dictionary for template rendering
|
||||
"""
|
||||
return {
|
||||
"metadata": metadata,
|
||||
"current_attempt": current_attempt,
|
||||
"max_attempts": max_attempts,
|
||||
"attempts_remaining": max(0, max_attempts - current_attempt),
|
||||
"current_section": current_section,
|
||||
"current_step": current_step,
|
||||
"username": username,
|
||||
}
|
||||
239
auth.py
|
|
@ -1,239 +0,0 @@
|
|||
"""Authentication module for email OTP-based authentication"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import smtplib
|
||||
import socket
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
|
||||
from flask import session, jsonify, request
|
||||
from models import db, User, OTPToken
|
||||
|
||||
|
||||
def generate_otp():
|
||||
"""Generate a 6-digit OTP code"""
|
||||
return ''.join([str(random.randint(0, 9)) for _ in range(6)])
|
||||
|
||||
|
||||
def send_otp_email(email, otp_code):
|
||||
"""Send OTP code to user's email via SMTP
|
||||
|
||||
Attempts to send via localhost:25 first. If that fails, tries configured SMTP.
|
||||
Falls back to console output if all methods fail.
|
||||
|
||||
Optional environment variables (only needed if localhost SMTP unavailable):
|
||||
- SMTP_HOST: SMTP server hostname (e.g., smtp.gmail.com)
|
||||
- SMTP_PORT: SMTP server port (e.g., 587)
|
||||
- SMTP_USER: SMTP username/email
|
||||
- SMTP_PASSWORD: SMTP password or app-specific password
|
||||
- SMTP_FROM_EMAIL: Email address to send from (auto-detected if not set)
|
||||
- SMTP_FROM_NAME: Display name for sender
|
||||
"""
|
||||
smtp_host = os.environ.get('SMTP_HOST')
|
||||
smtp_port = int(os.environ.get('SMTP_PORT', '587')) if smtp_host else 587
|
||||
smtp_user = os.environ.get('SMTP_USER')
|
||||
smtp_password = os.environ.get('SMTP_PASSWORD')
|
||||
|
||||
# Auto-detect sender email domain from request or hostname
|
||||
def get_default_from_email():
|
||||
# Try to get domain from Flask request context
|
||||
try:
|
||||
host = request.host
|
||||
# Skip localhost/127.0.0.1
|
||||
if host and not host.startswith('localhost') and not host.startswith('127.0.0.1'):
|
||||
# Remove port if present
|
||||
domain = host.split(':')[0]
|
||||
return f'noreply@{domain}'
|
||||
except RuntimeError:
|
||||
# No request context available
|
||||
pass
|
||||
|
||||
# Fall back to system hostname
|
||||
try:
|
||||
hostname = socket.getfqdn()
|
||||
if hostname and hostname != 'localhost':
|
||||
return f'noreply@{hostname}'
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Final fallback
|
||||
return smtp_user or 'noreply@opencompletion.local'
|
||||
|
||||
from_email = os.environ.get('SMTP_FROM_EMAIL', get_default_from_email())
|
||||
from_name = os.environ.get('SMTP_FROM_NAME', 'OpenCompletion')
|
||||
|
||||
# Create message
|
||||
msg = MIMEMultipart('alternative')
|
||||
msg['Subject'] = f'Your OpenCompletion verification code: {otp_code}'
|
||||
msg['From'] = f'{from_name} <{from_email}>'
|
||||
msg['To'] = email
|
||||
|
||||
# Plain text version
|
||||
text = f"""
|
||||
Your OpenCompletion verification code is: {otp_code}
|
||||
|
||||
This code will expire in 10 minutes.
|
||||
|
||||
If you didn't request this code, you can safely ignore this email.
|
||||
"""
|
||||
|
||||
# HTML version
|
||||
html = f"""
|
||||
<html>
|
||||
<body style="font-family: Arial, sans-serif; padding: 20px;">
|
||||
<h2>Your OpenCompletion Verification Code</h2>
|
||||
<p>Enter this code to complete your authentication:</p>
|
||||
<h1 style="background-color: #f0f0f0; padding: 15px; text-align: center; letter-spacing: 5px;">
|
||||
{otp_code}
|
||||
</h1>
|
||||
<p style="color: #666;">This code will expire in 10 minutes.</p>
|
||||
<p style="color: #999; font-size: 12px;">
|
||||
If you didn't request this code, you can safely ignore this email.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
# Attach both versions
|
||||
msg.attach(MIMEText(text, 'plain'))
|
||||
msg.attach(MIMEText(html, 'html'))
|
||||
|
||||
# Try localhost:25 first (common for development with local mail server)
|
||||
try:
|
||||
with smtplib.SMTP('localhost', 25, timeout=2) as server:
|
||||
server.send_message(msg)
|
||||
print(f"[INFO] OTP sent via localhost:25 to {email}")
|
||||
return True
|
||||
except (ConnectionRefusedError, OSError, smtplib.SMTPException) as e:
|
||||
# Localhost not available, try configured SMTP if available
|
||||
if smtp_host and smtp_user and smtp_password:
|
||||
try:
|
||||
with smtplib.SMTP(smtp_host, smtp_port, timeout=10) as server:
|
||||
server.starttls()
|
||||
server.login(smtp_user, smtp_password)
|
||||
server.send_message(msg)
|
||||
print(f"[INFO] OTP sent via {smtp_host} to {email}")
|
||||
return True
|
||||
except Exception as smtp_error:
|
||||
print(f"[ERROR] Failed to send OTP via {smtp_host}: {smtp_error}")
|
||||
|
||||
# Fall back to console output
|
||||
print(f"\n{'='*60}")
|
||||
print(f"[DEVELOPMENT] OTP Email - localhost:25 unavailable")
|
||||
print(f"{'='*60}")
|
||||
print(f"To: {email}")
|
||||
print(f"Subject: Your OpenCompletion verification code: {otp_code}")
|
||||
print(f"\nOTP CODE: {otp_code}")
|
||||
print(f"\nThis code expires in 10 minutes.")
|
||||
print(f"{'='*60}\n")
|
||||
# Return True to allow development workflow
|
||||
return True
|
||||
|
||||
|
||||
def create_otp_token(email):
|
||||
"""Create and store an OTP token for the given email"""
|
||||
# Invalidate any existing unused OTP tokens for this email
|
||||
existing_tokens = OTPToken.query.filter_by(email=email, used=False).all()
|
||||
for token in existing_tokens:
|
||||
token.used = True
|
||||
|
||||
# Generate new OTP
|
||||
otp_code = generate_otp()
|
||||
otp_token = OTPToken(email=email, otp_code=otp_code)
|
||||
|
||||
db.session.add(otp_token)
|
||||
db.session.commit()
|
||||
|
||||
return otp_token
|
||||
|
||||
|
||||
def verify_otp(email, otp_code):
|
||||
"""Verify an OTP code for the given email
|
||||
|
||||
Returns:
|
||||
- OTPToken object if valid
|
||||
- None if invalid
|
||||
"""
|
||||
otp_token = OTPToken.query.filter_by(
|
||||
email=email,
|
||||
otp_code=otp_code,
|
||||
used=False
|
||||
).first()
|
||||
|
||||
if otp_token and otp_token.is_valid():
|
||||
# Mark as used
|
||||
otp_token.used = True
|
||||
db.session.commit()
|
||||
return otp_token
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_or_create_user(email):
|
||||
"""Get existing user by email or return None if doesn't exist"""
|
||||
return User.query.filter_by(email=email).first()
|
||||
|
||||
|
||||
def create_user(email, display_name):
|
||||
"""Create a new user with email and display name"""
|
||||
# Check if display name is already taken
|
||||
existing_user = User.query.filter_by(display_name=display_name).first()
|
||||
if existing_user:
|
||||
return None, "Display name already taken"
|
||||
|
||||
# Check if email already exists
|
||||
existing_email = User.query.filter_by(email=email).first()
|
||||
if existing_email:
|
||||
return None, "Email already registered"
|
||||
|
||||
user = User(email=email, display_name=display_name)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
return user, None
|
||||
|
||||
|
||||
def login_user(user):
|
||||
"""Create session for authenticated user"""
|
||||
session['user_id'] = user.id
|
||||
session['user_email'] = user.email
|
||||
session['display_name'] = user.display_name
|
||||
session.permanent = True # Use permanent session
|
||||
|
||||
# Update last login
|
||||
user.last_login = datetime.utcnow()
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def logout_user():
|
||||
"""Clear user session"""
|
||||
session.pop('user_id', None)
|
||||
session.pop('user_email', None)
|
||||
session.pop('display_name', None)
|
||||
|
||||
|
||||
def get_current_user():
|
||||
"""Get currently authenticated user from session"""
|
||||
user_id = session.get('user_id')
|
||||
if user_id:
|
||||
return User.query.get(user_id)
|
||||
return None
|
||||
|
||||
|
||||
def require_auth(f):
|
||||
"""Decorator to require authentication for a route"""
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
user = get_current_user()
|
||||
if not user:
|
||||
return jsonify({'error': 'Authentication required'}), 401
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
|
||||
def is_authenticated():
|
||||
"""Check if current request is authenticated"""
|
||||
return 'user_id' in session
|
||||
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 854 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 121 KiB |
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
# make sure your python virtual env is already sourced and active.
|
||||
export CMAKE_ARGS="-DLLAMA_CUBLAS=on"
|
||||
export FORCE_CMAKE=1
|
||||
pip install --upgrade llama-cpp-python[server]
|
||||
|
||||
|
|
@ -12,31 +12,32 @@ config = context.config
|
|||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
fileConfig(config.config_file_name)
|
||||
logger = logging.getLogger("alembic.env")
|
||||
logger = logging.getLogger('alembic.env')
|
||||
|
||||
|
||||
def get_engine():
|
||||
try:
|
||||
# this works with Flask-SQLAlchemy<3 and Alchemical
|
||||
return current_app.extensions["migrate"].db.get_engine()
|
||||
return current_app.extensions['migrate'].db.get_engine()
|
||||
except (TypeError, AttributeError):
|
||||
# this works with Flask-SQLAlchemy>=3
|
||||
return current_app.extensions["migrate"].db.engine
|
||||
return current_app.extensions['migrate'].db.engine
|
||||
|
||||
|
||||
def get_engine_url():
|
||||
try:
|
||||
return get_engine().url.render_as_string(hide_password=False).replace("%", "%%")
|
||||
return get_engine().url.render_as_string(hide_password=False).replace(
|
||||
'%', '%%')
|
||||
except AttributeError:
|
||||
return str(get_engine().url).replace("%", "%%")
|
||||
return str(get_engine().url).replace('%', '%%')
|
||||
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
config.set_main_option("sqlalchemy.url", get_engine_url())
|
||||
target_db = current_app.extensions["migrate"].db
|
||||
config.set_main_option('sqlalchemy.url', get_engine_url())
|
||||
target_db = current_app.extensions['migrate'].db
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
|
|
@ -45,7 +46,7 @@ target_db = current_app.extensions["migrate"].db
|
|||
|
||||
|
||||
def get_metadata():
|
||||
if hasattr(target_db, "metadatas"):
|
||||
if hasattr(target_db, 'metadatas'):
|
||||
return target_db.metadatas[None]
|
||||
return target_db.metadata
|
||||
|
||||
|
|
@ -63,7 +64,9 @@ def run_migrations_offline():
|
|||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(url=url, target_metadata=get_metadata(), literal_binds=True)
|
||||
context.configure(
|
||||
url=url, target_metadata=get_metadata(), literal_binds=True
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
|
@ -81,13 +84,13 @@ def run_migrations_online():
|
|||
# when there are no changes to the schema
|
||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||
def process_revision_directives(context, revision, directives):
|
||||
if getattr(config.cmd_opts, "autogenerate", False):
|
||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
||||
script = directives[0]
|
||||
if script.upgrade_ops.is_empty():
|
||||
directives[:] = []
|
||||
logger.info("No changes in schema detected.")
|
||||
logger.info('No changes in schema detected.')
|
||||
|
||||
conf_args = current_app.extensions["migrate"].configure_args
|
||||
conf_args = current_app.extensions['migrate'].configure_args
|
||||
if conf_args.get("process_revision_directives") is None:
|
||||
conf_args["process_revision_directives"] = process_revision_directives
|
||||
|
||||
|
|
@ -95,7 +98,9 @@ def run_migrations_online():
|
|||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
connection=connection, target_metadata=get_metadata(), **conf_args
|
||||
connection=connection,
|
||||
target_metadata=get_metadata(),
|
||||
**conf_args
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
|
|
|
|||
|
|
@ -5,25 +5,23 @@ Revises: a9e886c56482
|
|||
Create Date: 2023-12-07 08:55:50.378439
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "190d5ef26e20"
|
||||
down_revision = "a9e886c56482"
|
||||
revision = '190d5ef26e20'
|
||||
down_revision = 'a9e886c56482'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from app import Message
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("message", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("token_count", sa.Integer(), nullable=True))
|
||||
with op.batch_alter_table('message', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('token_count', sa.Integer(), nullable=True))
|
||||
|
||||
# Use this binding to connect to the database
|
||||
bind = op.get_bind()
|
||||
|
|
@ -34,11 +32,10 @@ def upgrade():
|
|||
for message in messages:
|
||||
message.count_tokens()
|
||||
session.add(message)
|
||||
|
||||
session.commit()
|
||||
session.commit()
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("message", schema=None) as batch_op:
|
||||
batch_op.drop_column("token_count")
|
||||
with op.batch_alter_table('message', schema=None) as batch_op:
|
||||
batch_op.drop_column('token_count')
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
"""user session table
|
||||
|
||||
Revision ID: 1ac5a8e0f577
|
||||
Revises: 38a330686a17
|
||||
Create Date: 2024-11-23 11:25:01.723169
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import sqlite
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "1ac5a8e0f577"
|
||||
down_revision = "38a330686a17"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table(
|
||||
"user_session",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("session_id", sa.String(length=128), nullable=False),
|
||||
sa.Column("username", sa.String(length=128), nullable=True),
|
||||
sa.Column("room_name", sa.String(length=128), nullable=True),
|
||||
sa.Column("room_id", sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.UniqueConstraint("session_id"),
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_table("user_session")
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
"""Add authentication system with User, OTPToken models and Room ownership fields
|
||||
|
||||
Revision ID: 2025011100
|
||||
Revises: 5d93cdf18549
|
||||
Create Date: 2025-01-11 00:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import sqlite
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "2025011100"
|
||||
down_revision = "5d93cdf18549"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Add new columns to Room table
|
||||
# Note: User and OTPToken tables are created by db.create_all() in make init-db
|
||||
# Check if columns exist before adding (in case db.create_all() was run first)
|
||||
|
||||
conn = op.get_bind()
|
||||
inspector = sa.inspect(conn)
|
||||
columns = [col['name'] for col in inspector.get_columns('room')]
|
||||
|
||||
if 'is_private' not in columns:
|
||||
op.add_column('room', sa.Column('is_private', sa.Boolean(), nullable=False, server_default='0'))
|
||||
|
||||
if 'is_archived' not in columns:
|
||||
op.add_column('room', sa.Column('is_archived', sa.Boolean(), nullable=False, server_default='0'))
|
||||
|
||||
if 'owner_id' not in columns:
|
||||
op.add_column('room', sa.Column('owner_id', sa.Integer(), nullable=True))
|
||||
|
||||
if 'created_at' not in columns:
|
||||
op.add_column('room', sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')))
|
||||
|
||||
if 'forked_from_id' not in columns:
|
||||
op.add_column('room', sa.Column('forked_from_id', sa.Integer(), nullable=True))
|
||||
|
||||
# Create indexes (check if they exist first)
|
||||
indexes = [idx['name'] for idx in inspector.get_indexes('room')]
|
||||
|
||||
if 'ix_room_is_private' not in indexes:
|
||||
op.create_index(op.f('ix_room_is_private'), 'room', ['is_private'], unique=False)
|
||||
|
||||
if 'ix_room_is_archived' not in indexes:
|
||||
op.create_index(op.f('ix_room_is_archived'), 'room', ['is_archived'], unique=False)
|
||||
|
||||
if 'ix_room_owner_id' not in indexes:
|
||||
op.create_index(op.f('ix_room_owner_id'), 'room', ['owner_id'], unique=False)
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
"""room active users
|
||||
|
||||
Revision ID: 38a330686a17
|
||||
Revises: d737de68d6fa
|
||||
Create Date: 2024-11-23 09:52:50.824162
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import sqlite
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "38a330686a17"
|
||||
down_revision = "d737de68d6fa"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table("room", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("active_users", sa.Text(), nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table("room", schema=None) as batch_op:
|
||||
batch_op.drop_column("active_users")
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
"""add_updated_at_to_room
|
||||
|
||||
Revision ID: 5d0d533ff7c0
|
||||
Revises: 2025011100
|
||||
Create Date: 2025-11-11 21:53:13.141580
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5d0d533ff7c0'
|
||||
down_revision = '2025011100'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Add updated_at column to room table (Unix timestamp as integer)
|
||||
with op.batch_alter_table('room', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('updated_at', sa.Integer(), nullable=False, server_default=sa.text('(strftime(\'%s\', \'now\'))')))
|
||||
|
||||
|
||||
def downgrade():
|
||||
# Remove updated_at column from room table
|
||||
with op.batch_alter_table('room', schema=None) as batch_op:
|
||||
batch_op.drop_column('updated_at')
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
"""room inactive_users column
|
||||
|
||||
Revision ID: 5d93cdf18549
|
||||
Revises: 1ac5a8e0f577
|
||||
Create Date: 2024-11-24 14:04:30.488155
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import sqlite
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "5d93cdf18549"
|
||||
down_revision = "1ac5a8e0f577"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table("room", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("inactive_users", sa.Text(), nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table("room", schema=None) as batch_op:
|
||||
batch_op.drop_column("inactive_users")
|
||||
|
|
@ -3,36 +3,36 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.sql import table, column, select
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "a9e886c56482"
|
||||
revision = 'a9e886c56482'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Create room table
|
||||
op.create_table(
|
||||
"room",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("name", sa.String(length=128), nullable=False),
|
||||
sa.Column("title", sa.String(length=128), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.UniqueConstraint("name"),
|
||||
op.create_table('room',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=128), nullable=False),
|
||||
sa.Column('title', sa.String(length=128), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('name')
|
||||
)
|
||||
|
||||
# Add room_id column to message table
|
||||
op.add_column("message", sa.Column("room_id", sa.Integer(), nullable=True))
|
||||
op.add_column('message', sa.Column('room_id', sa.Integer(), nullable=True))
|
||||
|
||||
# Temporary table objects
|
||||
message_table = table(
|
||||
"message",
|
||||
column("id", sa.Integer),
|
||||
column("username", sa.String),
|
||||
column("content", sa.String),
|
||||
column("room", sa.String),
|
||||
column("room_id", sa.Integer),
|
||||
message_table = table('message',
|
||||
column('id', sa.Integer),
|
||||
column('username', sa.String),
|
||||
column('content', sa.String),
|
||||
column('room', sa.String),
|
||||
column('room_id', sa.Integer),
|
||||
)
|
||||
room_table = table('room',
|
||||
column('id', sa.Integer),
|
||||
column('name', sa.String)
|
||||
)
|
||||
room_table = table("room", column("id", sa.Integer), column("name", sa.String))
|
||||
|
||||
# Execution context
|
||||
conn = op.get_bind()
|
||||
|
|
@ -40,86 +40,74 @@ def upgrade():
|
|||
# Insert distinct rooms into room table and create mapping
|
||||
distinct_rooms = conn.execute(select(message_table.c.room).distinct())
|
||||
room_name_to_id = {}
|
||||
for (room_name,) in distinct_rooms:
|
||||
for room_name, in distinct_rooms:
|
||||
conn.execute(room_table.insert().values(name=room_name))
|
||||
room_id = conn.execute(
|
||||
select(room_table.c.id).where(room_table.c.name == room_name)
|
||||
).scalar()
|
||||
room_id = conn.execute(select(room_table.c.id).where(room_table.c.name == room_name)).scalar()
|
||||
room_name_to_id[room_name] = room_id
|
||||
|
||||
# Update message table with room_id
|
||||
for room_name, room_id in room_name_to_id.items():
|
||||
conn.execute(
|
||||
message_table.update()
|
||||
.where(message_table.c.room == room_name)
|
||||
.values(room_id=room_id)
|
||||
)
|
||||
conn.execute(message_table.update().where(message_table.c.room == room_name).values(room_id=room_id))
|
||||
|
||||
# Create new_message table
|
||||
new_message_table = op.create_table(
|
||||
"new_message",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("username", sa.String(length=128), nullable=False),
|
||||
sa.Column("content", sa.String(length=1024), nullable=False),
|
||||
sa.Column("room_id", sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(["room_id"], ["room.id"]),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
new_message_table = op.create_table('new_message',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=128), nullable=False),
|
||||
sa.Column('content', sa.String(length=1024), nullable=False),
|
||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['room_id'], ['room.id']),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
# Copy data from old message table to new_message table
|
||||
old_messages = conn.execute(sa.select(message_table)).fetchall()
|
||||
for old_message in old_messages:
|
||||
conn.execute(
|
||||
new_message_table.insert().values(
|
||||
id=old_message.id,
|
||||
username=old_message.username,
|
||||
content=old_message.content,
|
||||
room_id=old_message.room_id,
|
||||
)
|
||||
)
|
||||
conn.execute(new_message_table.insert().values(
|
||||
id=old_message.id,
|
||||
username=old_message.username,
|
||||
content=old_message.content,
|
||||
room_id=old_message.room_id
|
||||
))
|
||||
|
||||
# Drop old message table and rename new_message to message
|
||||
op.drop_table("message")
|
||||
op.rename_table("new_message", "message")
|
||||
|
||||
op.drop_table('message')
|
||||
op.rename_table('new_message', 'message')
|
||||
|
||||
def downgrade():
|
||||
# Recreate old_message table with 'room' column
|
||||
old_message_table = op.create_table(
|
||||
"old_message",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("username", sa.String(length=128), nullable=False),
|
||||
sa.Column("content", sa.String(length=1024), nullable=False),
|
||||
sa.Column("room", sa.String(length=128), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
old_message_table = op.create_table('old_message',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=128), nullable=False),
|
||||
sa.Column('content', sa.String(length=1024), nullable=False),
|
||||
sa.Column('room', sa.String(length=128), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
# Copy data back from message to old_message
|
||||
message_table = table(
|
||||
"message",
|
||||
column("id", sa.Integer),
|
||||
column("username", sa.String),
|
||||
column("content", sa.String),
|
||||
column("room_id", sa.Integer),
|
||||
message_table = table('message',
|
||||
column('id', sa.Integer),
|
||||
column('username', sa.String),
|
||||
column('content', sa.String),
|
||||
column('room_id', sa.Integer)
|
||||
)
|
||||
room_table = table('room',
|
||||
column('id', sa.Integer),
|
||||
column('name', sa.String)
|
||||
)
|
||||
room_table = table("room", column("id", sa.Integer), column("name", sa.String))
|
||||
|
||||
conn = op.get_bind()
|
||||
messages = conn.execute(select(message_table)).fetchall()
|
||||
for message in messages:
|
||||
room_name = conn.execute(
|
||||
select(room_table.c.name).where(room_table.c.id == message.room_id)
|
||||
).scalar()
|
||||
conn.execute(
|
||||
old_message_table.insert().values(
|
||||
id=message.id,
|
||||
username=message.username,
|
||||
content=message.content,
|
||||
room=room_name,
|
||||
)
|
||||
)
|
||||
room_name = conn.execute(select(room_table.c.name).where(room_table.c.id == message.room_id)).scalar()
|
||||
conn.execute(old_message_table.insert().values(
|
||||
id=message.id,
|
||||
username=message.username,
|
||||
content=message.content,
|
||||
room=room_name
|
||||
))
|
||||
|
||||
# Drop current message table and rename old_message to message
|
||||
op.drop_table("message")
|
||||
op.rename_table("old_message", "message")
|
||||
op.drop_table("room")
|
||||
op.drop_table('message')
|
||||
op.rename_table('old_message', 'message')
|
||||
op.drop_table('room')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
"""Add ActivityState table2
|
||||
|
||||
Revision ID: d04950c5a624
|
||||
Revises: d3631b8bb652
|
||||
Create Date: 2024-07-27 09:36:50.422693
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "d04950c5a624"
|
||||
down_revision = "d3631b8bb652"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("activity_state", schema=None) as batch_op:
|
||||
batch_op.add_column(
|
||||
sa.Column("s3_file_path", sa.String(length=256), nullable=False)
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("activity_state", schema=None) as batch_op:
|
||||
batch_op.drop_column("s3_file_path")
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
"""Add ActivityState table
|
||||
|
||||
Revision ID: d3631b8bb652
|
||||
Revises: 190d5ef26e20
|
||||
Create Date: 2024-07-27 09:33:52.544550
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "d3631b8bb652"
|
||||
down_revision = "190d5ef26e20"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"activity_state",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("room_id", sa.Integer(), nullable=False),
|
||||
sa.Column("section_id", sa.String(length=128), nullable=False),
|
||||
sa.Column("step_id", sa.String(length=128), nullable=False),
|
||||
sa.Column("attempts", sa.Integer(), nullable=True),
|
||||
sa.Column("max_attempts", sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["room_id"],
|
||||
["room.id"],
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table("activity_state")
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
"""Add metadata field to ActivityState
|
||||
|
||||
Revision ID: d737de68d6fa
|
||||
Revises: d04950c5a624
|
||||
Create Date: 2024-07-28 17:02:11.872502
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "d737de68d6fa"
|
||||
down_revision = "d04950c5a624"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("activity_state", schema=None) as batch_op:
|
||||
batch_op.add_column(
|
||||
sa.Column("json_metadata", sa.UnicodeText(), server_default="{}")
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table("activity_state", schema=None) as batch_op:
|
||||
batch_op.drop_column("json_metadata")
|
||||
|
||||
# ### end Alembic commands ###
|
||||
178
models.py
|
|
@ -1,178 +0,0 @@
|
|||
from flask_sqlalchemy import SQLAlchemy
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import os
|
||||
try:
|
||||
import tiktoken
|
||||
TIKTOKEN_AVAILABLE = True
|
||||
except Exception:
|
||||
TIKTOKEN_AVAILABLE = False
|
||||
tiktoken = None
|
||||
|
||||
import json
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
|
||||
class User(db.Model):
|
||||
"""User model for authentication and ownership"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
email = db.Column(db.String(255), unique=True, nullable=False, index=True)
|
||||
display_name = db.Column(db.String(50), unique=True, nullable=False, index=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
last_login = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
# Relationships
|
||||
owned_rooms = db.relationship('Room', backref='owner', lazy='dynamic', foreign_keys='Room.owner_id')
|
||||
|
||||
def __repr__(self):
|
||||
return f'<User {self.display_name} ({self.email})>'
|
||||
|
||||
|
||||
class OTPToken(db.Model):
|
||||
"""One-Time Password tokens for email authentication"""
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
email = db.Column(db.String(255), nullable=False, index=True)
|
||||
otp_code = db.Column(db.String(6), nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
expires_at = db.Column(db.DateTime, nullable=False)
|
||||
used = db.Column(db.Boolean, default=False, nullable=False)
|
||||
|
||||
def __init__(self, email, otp_code, expiration_minutes=10):
|
||||
self.email = email
|
||||
self.otp_code = otp_code
|
||||
self.created_at = datetime.utcnow()
|
||||
self.expires_at = self.created_at + timedelta(minutes=expiration_minutes)
|
||||
self.used = False
|
||||
|
||||
def is_valid(self):
|
||||
"""Check if the OTP is still valid (not used and not expired)"""
|
||||
return not self.used and datetime.utcnow() < self.expires_at
|
||||
|
||||
def __repr__(self):
|
||||
return f'<OTPToken {self.email} expires_at={self.expires_at}>'
|
||||
|
||||
|
||||
class Room(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(128), nullable=False, unique=True)
|
||||
title = db.Column(db.String(128), nullable=True)
|
||||
active_users = db.Column(db.Text, default="") # Store as a comma-separated string
|
||||
inactive_users = db.Column(db.Text, default="") # Store as a comma-separated string
|
||||
is_private = db.Column(db.Boolean, default=False, nullable=False, index=True)
|
||||
is_archived = db.Column(db.Boolean, default=False, nullable=False, index=True)
|
||||
owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True, index=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
updated_at = db.Column(db.Integer, default=lambda: int(datetime.utcnow().timestamp()), nullable=False)
|
||||
forked_from_id = db.Column(db.Integer, db.ForeignKey('room.id'), nullable=True)
|
||||
|
||||
def add_user(self, username):
|
||||
active_users = set(self.active_users.split(",")) if self.active_users else set()
|
||||
inactive_users = (
|
||||
set(self.inactive_users.split(",")) if self.inactive_users else set()
|
||||
)
|
||||
|
||||
# Move from inactive to active if necessary
|
||||
if username in inactive_users:
|
||||
inactive_users.discard(username)
|
||||
|
||||
active_users.add(username)
|
||||
self.active_users = ",".join(sorted(active_users))
|
||||
self.inactive_users = ",".join(sorted(inactive_users))
|
||||
|
||||
def remove_user(self, username):
|
||||
active_users = set(self.active_users.split(",")) if self.active_users else set()
|
||||
inactive_users = (
|
||||
set(self.inactive_users.split(",")) if self.inactive_users else set()
|
||||
)
|
||||
|
||||
if username in active_users:
|
||||
active_users.discard(username)
|
||||
inactive_users.add(username) # Move to inactive users
|
||||
|
||||
self.active_users = ",".join(sorted(active_users))
|
||||
self.inactive_users = ",".join(sorted(inactive_users))
|
||||
|
||||
def get_active_users(self):
|
||||
return self.active_users.split(",") if self.active_users else []
|
||||
|
||||
def get_inactive_users(self):
|
||||
return self.inactive_users.split(",") if self.inactive_users else []
|
||||
|
||||
|
||||
class UserSession(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
session_id = db.Column(db.String(128), unique=True, nullable=False)
|
||||
username = db.Column(db.String(128))
|
||||
room_name = db.Column(db.String(128))
|
||||
room_id = db.Column(db.Integer)
|
||||
|
||||
|
||||
class Message(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(128), nullable=False)
|
||||
content = db.Column(db.String(1024), nullable=False)
|
||||
token_count = db.Column(db.Integer)
|
||||
room_id = db.Column(db.Integer, db.ForeignKey("room.id"), nullable=False)
|
||||
|
||||
def __init__(self, username, content, room_id):
|
||||
self.username = username
|
||||
self.content = content
|
||||
self.room_id = room_id
|
||||
self.count_tokens()
|
||||
|
||||
def count_tokens(self):
|
||||
if self.token_count is None:
|
||||
if self.is_base64_image():
|
||||
self.token_count = 0
|
||||
elif not TIKTOKEN_AVAILABLE:
|
||||
# Fallback: estimate ~4 chars per token when tiktoken unavailable
|
||||
self.token_count = len(self.content) // 4 + 1
|
||||
else:
|
||||
try:
|
||||
encoding = tiktoken.encoding_for_model("gpt-4")
|
||||
self.token_count = len(encoding.encode(self.content))
|
||||
except Exception:
|
||||
# Fallback on any tiktoken error (network, SSL, etc.)
|
||||
self.token_count = len(self.content) // 4 + 1
|
||||
return self.token_count
|
||||
|
||||
def is_base64_image(self):
|
||||
"""Check if message contains a base64-encoded image."""
|
||||
if not self.content:
|
||||
return False
|
||||
# Check for any base64 image (jpeg, png, gif, webp, etc.)
|
||||
return '<img' in self.content and 'data:image/' in self.content and ';base64,' in self.content
|
||||
|
||||
|
||||
class ActivityState(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
room_id = db.Column(db.Integer, db.ForeignKey("room.id"), nullable=False)
|
||||
section_id = db.Column(db.String(128), nullable=False)
|
||||
step_id = db.Column(db.String(128), nullable=False)
|
||||
attempts = db.Column(db.Integer, default=0)
|
||||
max_attempts = db.Column(db.Integer, default=3)
|
||||
s3_file_path = db.Column(db.String(256), nullable=False)
|
||||
json_metadata = db.Column(db.UnicodeText, default="{}")
|
||||
|
||||
@property
|
||||
def dict_metadata(self):
|
||||
return json.loads(self.json_metadata) if self.json_metadata else {}
|
||||
|
||||
@dict_metadata.setter
|
||||
def dict_metadata(self, value):
|
||||
self.json_metadata = json.dumps(value)
|
||||
|
||||
def add_metadata(self, key, value):
|
||||
metadata = self.dict_metadata
|
||||
metadata[key] = value
|
||||
self.dict_metadata = metadata
|
||||
|
||||
def remove_metadata(self, key):
|
||||
metadata = self.dict_metadata
|
||||
if key in metadata:
|
||||
del metadata[key]
|
||||
self.dict_metadata = metadata
|
||||
|
||||
def clear_metadata(self):
|
||||
self.dict_metadata = {}
|
||||
17
pytest.ini
|
|
@ -1,17 +0,0 @@
|
|||
[pytest]
|
||||
testpaths = tests
|
||||
python_files = test_*.py
|
||||
python_classes = Test*
|
||||
python_functions = test_*
|
||||
addopts =
|
||||
-v
|
||||
--strict-markers
|
||||
--tb=short
|
||||
markers =
|
||||
unit: Unit tests
|
||||
integration: Integration tests
|
||||
functional: Functional tests
|
||||
slow: Slow-running tests
|
||||
env =
|
||||
SQLALCHEMY_DATABASE_URI=sqlite:///:memory:
|
||||
TESTING=1
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
pytest
|
||||
pytest-cov
|
||||
pytest-mock
|
||||
pytest-flask
|
||||
pytest-asyncio
|
||||
black
|
||||
flake8
|
||||
|
|
@ -1,28 +1,12 @@
|
|||
flask
|
||||
flask-socketio
|
||||
|
||||
#eventlet
|
||||
gevent
|
||||
gevent-websocket
|
||||
|
||||
eventlet
|
||||
mistralai
|
||||
openai
|
||||
openai[datalib]
|
||||
together
|
||||
|
||||
tiktoken
|
||||
|
||||
#llama-cpp-python[server]
|
||||
|
||||
# sqlite
|
||||
Flask-SQLAlchemy
|
||||
Flask-Migrate
|
||||
|
||||
# used for s3/spaces or aws bedrock (claude)
|
||||
boto3
|
||||
|
||||
pyyaml
|
||||
|
||||
# if you want to plot charts.
|
||||
matplotlib
|
||||
numpy
|
||||
sympy
|
||||
|
|
|
|||
|
|
@ -1,294 +0,0 @@
|
|||
# Educational Activities Implementation - Complete
|
||||
|
||||
## Project Summary
|
||||
|
||||
**Status**: ✅ COMPLETED
|
||||
**Total Activities Created**: 8 (activity30 - activity37)
|
||||
**Total Lines of YAML**: 6,112
|
||||
**Validation Status**: All activities passing with 0 errors
|
||||
|
||||
## Design Criteria (Achieved)
|
||||
|
||||
All activities successfully implemented with:
|
||||
1. ✅ **No embedded Python** - Pure YAML using buckets, transitions, metadata operations, AI feedback
|
||||
2. ✅ **Educational value** - Teach concepts through interaction and reflection
|
||||
3. ✅ **Engaging** - Mix of narrative, problem-solving, and critical thinking
|
||||
4. ✅ **Progressive** - Build knowledge step-by-step
|
||||
5. ✅ **Use AI effectively** - Separate classifier and feedback models for optimal performance
|
||||
6. ✅ **Follow schema** - All activities validated successfully
|
||||
|
||||
## New Feature: Model Configuration
|
||||
|
||||
All activities now support configurable AI models:
|
||||
|
||||
```yaml
|
||||
# Activity-level defaults
|
||||
classifier_model: "MODEL_1" # Fast classification (Hermes-3-Llama-3.1-8B)
|
||||
feedback_model: "MODEL_1" # Feedback generation (can override per activity)
|
||||
|
||||
# Step-level overrides (optional)
|
||||
- step_id: "code_review"
|
||||
classifier_model: "MODEL_1" # Keep Hermes for classification
|
||||
feedback_model: "MODEL_3" # Use Qwen3-Coder for code feedback
|
||||
```
|
||||
|
||||
### Model Recommendations
|
||||
|
||||
- **MODEL_1 (Hermes-3-Llama-3.1-8B)**:
|
||||
- Default for all activities
|
||||
- Always available in base install
|
||||
- Excellent for role-playing scenarios
|
||||
- Fast and accurate classification
|
||||
- Great general-purpose feedback
|
||||
|
||||
- **MODEL_3 (Qwen3-Coder-30B)**:
|
||||
- Specialized for programming (activity37)
|
||||
- Recommended: `hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M`
|
||||
- Supports 100+ programming languages
|
||||
- Expert code generation and debugging
|
||||
|
||||
## Completed Activities
|
||||
|
||||
### Initial Set (Activities 30-34)
|
||||
|
||||
| Activity | Lines | Topic | Status | Special Features |
|
||||
|----------|-------|-------|--------|-----------------|
|
||||
| **30** | 530 | Logic Puzzles | ✅ | Contrapositive, syllogisms, knights and knaves |
|
||||
| **31** | 651 | Scientific Method | ✅ | Historical case studies (Semmelweis, Newton) |
|
||||
| **32** | 796 | World Geography | ✅ | Choose-your-own-adventure, metadata path tracking |
|
||||
| **33** | 640 | Environmental Science | ✅ | Role-play as consultant, environmental score tracking |
|
||||
| **34** | 697 | Media Literacy | ✅ | Source evaluation, bias detection, fact-checking |
|
||||
|
||||
### Extended Set (Activities 35-37)
|
||||
|
||||
| Activity | Lines | Topic | Status | Special Features |
|
||||
|----------|-------|-------|--------|-----------------|
|
||||
| **35** | 981 | American History | ✅ | Advanced for gifted students, primary source analysis |
|
||||
| **36** | 877 | Biblical History | ✅ | Historical/archaeological approach, ancient Near East |
|
||||
| **37** | 700 | Programming Languages | ✅ | **Universal language support**, MODEL_3 (Qwen3-Coder) |
|
||||
|
||||
### Activity 37: Programming Languages (Flagship)
|
||||
|
||||
**Innovation**: First activity to leverage dual-model configuration
|
||||
|
||||
```yaml
|
||||
classifier_model: "MODEL_1" # Hermes for fast bucketing
|
||||
feedback_model: "MODEL_3" # Qwen3-Coder for code generation
|
||||
```
|
||||
|
||||
**How it works**:
|
||||
1. Student chooses ANY programming language (Python, Rust, COBOL, etc.)
|
||||
2. Choice stored in metadata: `programming_language: "user-choice"`
|
||||
3. AI adapts ALL code examples to chosen language via `tokens_for_ai`
|
||||
4. Qwen3-Coder generates language-specific syntax and explanations
|
||||
5. Covers: Hello World, variables, control flow, loops, functions (all using stdout)
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### YAML-Only Features Used
|
||||
|
||||
- **Buckets**: Response categorization (correct, partial_understanding, off_topic)
|
||||
- **Transitions**: Navigation between steps based on buckets
|
||||
- **Metadata Operations**:
|
||||
- `metadata_add`: Persistent state
|
||||
- `metadata_tmp_add`: Single-turn state
|
||||
- `metadata_remove`: State cleanup
|
||||
- `metadata_clear`: Reset all state
|
||||
- **AI Feedback**:
|
||||
- `tokens_for_ai`: Classification instructions
|
||||
- `feedback_tokens_for_ai`: Feedback generation instructions
|
||||
- `tokens_for_ai_rubric`: Final evaluation rubric
|
||||
- **Model Selection**:
|
||||
- `classifier_model`: Per-activity or per-step classification model
|
||||
- `feedback_model`: Per-activity or per-step feedback model
|
||||
|
||||
### Validation
|
||||
|
||||
All activities pass validation:
|
||||
```bash
|
||||
python activity_yaml_validator.py research/activity*.yaml
|
||||
# Result: 8 files, 0 errors, 0 warnings
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
CLI simulation tool supports model configuration:
|
||||
```bash
|
||||
source vars.sh
|
||||
python research/guarded_ai.py research/activity37-programming-languages.yaml
|
||||
# Uses MODEL_1 for classification, MODEL_3 for code feedback
|
||||
```
|
||||
|
||||
## Activity Diversity Achieved
|
||||
|
||||
### Subject Areas
|
||||
- **STEM**: Logic, Scientific Method, Environmental Science, Programming
|
||||
- **Humanities**: American History, Biblical History
|
||||
- **Social Studies**: Geography, Media Literacy
|
||||
|
||||
### Interaction Types
|
||||
- Puzzles (Logic, Programming)
|
||||
- Case Studies (Scientific Method, History)
|
||||
- Choose-Your-Own-Adventure (Geography)
|
||||
- Role-Playing (Environmental Science)
|
||||
- Evaluation (Media Literacy)
|
||||
|
||||
### Skills Developed
|
||||
- Logical reasoning
|
||||
- Scientific thinking
|
||||
- Cultural awareness
|
||||
- Systems thinking
|
||||
- Critical evaluation
|
||||
- Programming literacy
|
||||
|
||||
### Difficulty Range
|
||||
- **Beginner**: Geography basics, simple logic
|
||||
- **Intermediate**: Scientific method, environmental decisions
|
||||
- **Advanced**: American History critical analysis, programming language concepts
|
||||
|
||||
## Model Setup Guide
|
||||
|
||||
### Hermes-3-Llama-3.1-8B (MODEL_1)
|
||||
**Default model - included in base installation**
|
||||
|
||||
No setup required. Always available as fallback.
|
||||
|
||||
### Qwen3-Coder-30B (MODEL_3)
|
||||
**Recommended for activity37 - Programming Languages**
|
||||
|
||||
#### Option 1: llama.cpp
|
||||
```bash
|
||||
# Download model
|
||||
huggingface-cli download unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF \
|
||||
Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
|
||||
|
||||
# Run server (GPU acceleration with -ngl 99)
|
||||
llama-server -m Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf \
|
||||
--host 0.0.0.0 --port 8080 -ngl 99
|
||||
|
||||
# Set environment
|
||||
export MODEL_ENDPOINT_3=http://localhost:8080/v1
|
||||
export MODEL_API_KEY_3=dummy
|
||||
```
|
||||
|
||||
#### Option 2: ollama
|
||||
```bash
|
||||
ollama run unsloth/qwen3-coder:30b-instruct-q4_K_M
|
||||
|
||||
# Set environment
|
||||
export MODEL_ENDPOINT_3=http://localhost:11434/v1
|
||||
export MODEL_API_KEY_3=dummy
|
||||
```
|
||||
|
||||
#### Why Qwen3-Coder?
|
||||
- 30B parameters (much smarter than smaller models)
|
||||
- Q4_K_M quantization (~20GB RAM)
|
||||
- Trained on 100+ programming languages
|
||||
- Unsloth optimized for fast inference
|
||||
- Works offline
|
||||
|
||||
## Files Modified/Created
|
||||
|
||||
### New Files (8 activities)
|
||||
- `research/activity30-logic-puzzles.yaml` (530 lines)
|
||||
- `research/activity31-scientific-method.yaml` (651 lines)
|
||||
- `research/activity32-world-geography.yaml` (796 lines)
|
||||
- `research/activity33-environmental-science.yaml` (640 lines)
|
||||
- `research/activity34-media-literacy.yaml` (697 lines)
|
||||
- `research/activity35-american-history.yaml` (981 lines)
|
||||
- `research/activity36-biblical-history.yaml` (877 lines)
|
||||
- `research/activity37-programming-languages.yaml` (700 lines)
|
||||
|
||||
### Updated Files
|
||||
- `activity_yaml_validator.py`: Added `classifier_model` and `feedback_model` validation
|
||||
- `activity.py`: Model parameter support throughout all functions
|
||||
- `research/guarded_ai.py`: CLI simulator updated for dual-model configuration
|
||||
- `.gitignore`: Added `venv/`
|
||||
|
||||
## Key Implementation Decisions
|
||||
|
||||
### Why Separate Classifier and Feedback Models?
|
||||
|
||||
1. **Speed**: Classification is fast (Hermes 8B) → instant response bucketing
|
||||
2. **Quality**: Feedback can use specialized models → better explanations
|
||||
3. **Cost**: Don't need large model for simple categorization
|
||||
4. **Flexibility**: Override per-step for specific needs
|
||||
|
||||
### Why Hermes as Default?
|
||||
|
||||
1. **Availability**: Always included in base install
|
||||
2. **Speed**: 8B model is very fast
|
||||
3. **Quality**: Excellent at role-playing and general tasks
|
||||
4. **Reliability**: Stable fallback for all activities
|
||||
|
||||
### Why Qwen3-Coder for Programming?
|
||||
|
||||
1. **Specialization**: Trained specifically for code generation
|
||||
2. **Language Coverage**: Supports 100+ programming languages
|
||||
3. **Size**: 30B parameters → much smarter than 8B models
|
||||
4. **Accuracy**: Better at language-specific syntax and idioms
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Run an Activity (Web App)
|
||||
```bash
|
||||
source vars.sh
|
||||
python app.py
|
||||
# Navigate to http://localhost:5000
|
||||
# Select activity from dropdown
|
||||
```
|
||||
|
||||
### Test an Activity (CLI)
|
||||
```bash
|
||||
source vars.sh
|
||||
python research/guarded_ai.py research/activity37-programming-languages.yaml
|
||||
# Choose: Rust
|
||||
# Activity adapts all examples to Rust syntax
|
||||
```
|
||||
|
||||
### Validate All Activities
|
||||
```bash
|
||||
python activity_yaml_validator.py research/activity*.yaml
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Potential Model Combinations
|
||||
|
||||
1. **Fast Classification + Quality Feedback**:
|
||||
```yaml
|
||||
classifier_model: "MODEL_1" # Hermes 8B (fast)
|
||||
feedback_model: "MODEL_2" # Larger model (quality)
|
||||
```
|
||||
|
||||
2. **Domain-Specific Models**:
|
||||
- Science activities → Science-tuned model
|
||||
- History activities → Long-context model
|
||||
- Code activities → Code-specialized model
|
||||
|
||||
3. **Step-Level Overrides**:
|
||||
```yaml
|
||||
- step_id: "creative_writing"
|
||||
feedback_model: "MODEL_4" # Creative writing specialist
|
||||
|
||||
- step_id: "code_review"
|
||||
feedback_model: "MODEL_3" # Code specialist
|
||||
```
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
1. **Metadata is Powerful**: Can track complex state without Python
|
||||
2. **AI Adaptation**: `tokens_for_ai` enables universal activities (any language)
|
||||
3. **Model Separation**: Classification vs feedback needs different models
|
||||
4. **Hermes Excellence**: Great for role-playing scenarios (consultant, teacher)
|
||||
5. **Validation Critical**: Schema validation caught all errors early
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
All activities created without embedded Python, demonstrating the power of:
|
||||
- YAML-based activity framework
|
||||
- Metadata-driven state management
|
||||
- AI-powered personalization
|
||||
- Dual-model architecture
|
||||
|
||||
**Total Development**: 8 educational activities, 6,112 lines of YAML, 0 validation errors
|
||||
1147
research/SPEC.yaml
|
|
@ -1,662 +0,0 @@
|
|||
# Global Spiritual Time Machine - Biblical Timeline Edition
|
||||
# Travel to ANY location in the world during biblical times (~4000 BC - 313 AD)
|
||||
# Meet spiritual figures across cultures: biblical prophets, Greek philosophers, Buddhist monks, Hindu gurus, and more
|
||||
# The AI dynamically determines the time period, location, and spiritual context
|
||||
|
||||
default_max_attempts_per_step: 5
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are an intelligent GLOBAL time machine AI assistant.
|
||||
|
||||
Your job is to facilitate open-ended time travel to ANY location on Earth during the biblical timeline (~4000 BC - 313 AD).
|
||||
|
||||
KEY BEHAVIORS:
|
||||
- User can visit ANYWHERE: "30 AD Greece", "1000 BC India", "50 BC Rome", "Moses in Egypt", etc.
|
||||
- When user names TIME + PLACE, teleport there and explain spiritual context of that location/era
|
||||
- When user names just PERSON, determine when/where they lived
|
||||
- When user names just PLACE, ask what time period they want
|
||||
- Support biblical figures in biblical lands AND non-biblical spiritual figures elsewhere
|
||||
- Examples: Meet Jesus in Judea, Socrates in Athens, Buddha's followers in India, Zoroastrian priests in Persia
|
||||
|
||||
ACCURACY REQUIREMENTS:
|
||||
- Biblical lands: Maintain biblical accuracy (Temple status, geography, etc.)
|
||||
- Non-biblical regions: Provide historically accurate spiritual context for that time/place
|
||||
- Respect all spiritual traditions while facilitating exploration
|
||||
|
||||
CRITICAL: Be historically and culturally accurate for ALL regions and time periods.
|
||||
|
||||
sections:
|
||||
# ============================================================================
|
||||
# INTRODUCTION
|
||||
# ============================================================================
|
||||
- section_id: "introduction"
|
||||
title: "Biblical Time Machine"
|
||||
steps:
|
||||
- step_id: "welcome"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "# ⏳ Global Spiritual Time Machine ⏳"
|
||||
- ""
|
||||
- "You have discovered a time machine that can transport you to **ANY location on Earth** during the biblical timeline (~4000 BC - 313 AD)."
|
||||
- ""
|
||||
- "**Travel ANYWHERE:**"
|
||||
- "- 📍 **Biblical lands**: Meet Moses in Egypt, Jesus in Galilee, Daniel in Babylon"
|
||||
- "- 🏛️ **Ancient Greece**: Converse with Socrates in Athens, philosophers in Delphi"
|
||||
- "- 🏺 **Ancient Rome**: Meet Stoic philosophers, Roman priests, early Christians"
|
||||
- "- 🕉️ **India**: Explore Buddhist monasteries, meet Hindu gurus and yogis"
|
||||
- "- 🏮 **China**: Visit Confucian scholars, Taoist masters"
|
||||
- "- 🔥 **Persia**: Meet Zoroastrian priests, magi"
|
||||
- "- 🌍 **Anywhere else**: Africa, Arabia, Britain - all spiritual traditions welcome"
|
||||
- ""
|
||||
- "**Examples:**"
|
||||
- "- \"Take me to 30 AD Greece\""
|
||||
- "- \"I want to meet a Buddhist monk in India\""
|
||||
- "- \"Show me what's happening in Rome during Jesus' time\""
|
||||
- "- \"Moses\" (I'll figure out when/where!)"
|
||||
- ""
|
||||
- "The machine will calculate the time, place, and spiritual context."
|
||||
|
||||
- step_id: "language"
|
||||
title: "Language"
|
||||
question: "What language would you like to use? (English, Spanish, French, etc.)"
|
||||
tokens_for_ai: |
|
||||
User selecting language.
|
||||
|
||||
Categorize as 'set' for any language.
|
||||
Categorize as 'skip' if they want English or to skip.
|
||||
buckets: [set, skip]
|
||||
transitions:
|
||||
set:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
skip:
|
||||
metadata_add:
|
||||
language: "English"
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
|
||||
# ============================================================================
|
||||
# TIME MACHINE - OPEN-ENDED DESTINATION
|
||||
# ============================================================================
|
||||
- section_id: "time_machine"
|
||||
title: "Time Machine"
|
||||
steps:
|
||||
- step_id: "destination_input"
|
||||
title: "Where/When/Who"
|
||||
question: "Where and when would you like to go? Or who would you like to meet? (Examples: '30 AD Greece', 'Moses', '500 BC India', 'Socrates', 'END' to finish)"
|
||||
tokens_for_ai: |
|
||||
This is COMPLETELY OPEN-ENDED and GEOGRAPHY-AWARE. User can request:
|
||||
- TIME + PLACE: "30 AD Greece", "1000 BC India", "50 BC Rome"
|
||||
- PERSON: "Moses", "Jesus", "Socrates", "Buddha", "Confucius"
|
||||
- BIBLICAL EVENT: "Exodus", "Crucifixion", "Pentecost"
|
||||
- JUST PLACE: "Greece", "India", "Rome" (you'll need to ask what time period)
|
||||
|
||||
Your job: Determine what GEOGRAPHIC REGION they're requesting.
|
||||
|
||||
BIBLICAL LANDS (Israel, Judea, Canaan, Egypt in biblical context, Babylon in biblical context):
|
||||
- Garden of Eden, Adam, Eve, pre-Fall
|
||||
- Cain, Abel, Noah, Flood, early patriarchs
|
||||
- Abraham, Isaac, Jacob, Joseph
|
||||
- Moses, Exodus, Egypt (Hebrew context), Pharaoh, plagues
|
||||
- Joshua, Judges, Canaan conquest
|
||||
- Saul, David, Solomon, Jerusalem, kings, prophets
|
||||
- Babylon/Exile (Jewish exile specifically)
|
||||
- Jesus, disciples, Galilee, Judea, crucifixion, resurrection
|
||||
- Pentecost, early church, apostles, persecution IN ISRAEL
|
||||
- Paul in biblical lands specifically
|
||||
|
||||
NON-BIBLICAL WORLD REGIONS:
|
||||
- Greece: Athens, Sparta, Greek philosophers, mystery religions, Greek culture
|
||||
- Rome: Roman Empire, senators, philosophers, gladiators, Roman religion
|
||||
- India: Hinduism, Buddhism, yogis, gurus, monks, meditation
|
||||
- China: Confucianism, Taoism, Chinese philosophy, dynasties
|
||||
- Persia: Zoroastrianism, magi, Persian Empire
|
||||
- Other: Arabia, Africa (non-Egypt), Europe, Britain, any other location
|
||||
|
||||
Categorize as:
|
||||
- 'biblical_lands' for ANY biblical location, person, or event in Israel/Judea/Canaan/biblical Egypt/Babylon
|
||||
- 'greece' for Greece, Athens, Sparta, Greek philosophers, Greek culture, Greek anything
|
||||
- 'rome' for Rome, Roman Empire, Italy, Roman culture (unless Paul's biblical journey there)
|
||||
- 'india' for India, Hinduism, Buddhism, Indian culture, yogis, gurus
|
||||
- 'china' for China, Confucius, Taoism, Chinese philosophy, dynasties
|
||||
- 'persia' for Persia, Zoroastrianism, magi, Persian Empire
|
||||
- 'other_world' for anywhere else: Arabia, Africa, Europe, Britain, etc.
|
||||
- 'end' if END, finish, done, quit
|
||||
- 'unclear' if you genuinely can't determine
|
||||
buckets: [biblical_lands, greece, rome, india, china, persia, other_world, end, unclear]
|
||||
transitions:
|
||||
biblical_lands:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested biblical location/person/event: "the-users-response"
|
||||
|
||||
YOUR JOB: Dynamically generate a BRIEF departure briefing (3-5 sentences):
|
||||
|
||||
1. Determine SPECIFIC time period from their request:
|
||||
- Garden of Eden: ~4000 BC (pre-Fall)
|
||||
- Early world: ~4000-2350 BC (Cain, Abel, Noah, Flood)
|
||||
- Patriarchs: ~2000-1800 BC (Abraham, Isaac, Jacob, Joseph)
|
||||
- Exodus: ~1446 BC (Moses, Egypt, plagues, Red Sea)
|
||||
- Judges: ~1400-1050 BC (Joshua, Deborah, Gideon, Samson)
|
||||
- Kingdom: ~1000-586 BC (Saul, David, Solomon, kings, prophets)
|
||||
- Exile: ~586-538 BC (Babylon, Daniel, Ezekiel, Jeremiah)
|
||||
- Jesus: ~27-30 AD (ministry, miracles, teaching)
|
||||
- Crucifixion: ~30 AD Passover (cross, resurrection)
|
||||
- Early church: ~33-60 AD (Pentecost, apostles, Acts)
|
||||
- Paul: ~46-67 AD (missionary journeys, churches)
|
||||
- Persecution: ~64-313 AD (Rome, martyrs, catacombs)
|
||||
|
||||
2. Provide briefing with:
|
||||
- Destination (specific location)
|
||||
- Time period (approximate date)
|
||||
- Context (what's happening, who's there)
|
||||
- **CRITICAL**: Temple status (NO Temple before Solomon ~970 BC, FIRST Temple 970-586 BC, SECOND Temple 516 BC-70 AD, NO Temple after 70 AD)
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language for response.
|
||||
metadata_add:
|
||||
current_region: "Biblical Lands"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
greece:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested Greece: "the-users-response"
|
||||
|
||||
YOUR JOB: Dynamically generate briefing for Greece during requested time:
|
||||
|
||||
1. Determine time period from their request (or default to 400 BC if unclear):
|
||||
- ~800-500 BC: Archaic period, Homer, early city-states
|
||||
- ~500-323 BC: Classical period, Socrates (~470-399 BC), Plato (~428-348 BC), Aristotle (~384-322 BC)
|
||||
- ~323-31 BC: Hellenistic period, Alexander's legacy, philosophical schools
|
||||
- ~31 BC-313 AD: Roman Greece, Stoicism, Epicureanism, mystery religions
|
||||
|
||||
2. Provide briefing:
|
||||
- Destination: Athens, Delphi, Sparta, or relevant city
|
||||
- Time: Approximate date from their request
|
||||
- Spiritual context: Philosophers, mystery religions (Eleusinian, Dionysian), Greek gods (Zeus, Athena, Apollo), philosophical schools (Academy, Lyceum, Stoa)
|
||||
- Who's there: Philosophers, priests, citizens, travelers, mystery cult initiates
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "Greece"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
rome:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested Rome: "the-users-response"
|
||||
|
||||
YOUR JOB: Generate briefing for Rome during requested time:
|
||||
|
||||
1. Determine time period (or default to 50 BC if unclear):
|
||||
- ~753-509 BC: Roman Kingdom, founding myths, early religion
|
||||
- ~509-27 BC: Roman Republic, Cicero, Stoicism arriving
|
||||
- ~27 BC-313 AD: Roman Empire, emperors, imperial cult, gladiators, Colosseum
|
||||
- ~64-313 AD: Christian persecution, catacombs, martyrs
|
||||
|
||||
2. Provide briefing:
|
||||
- Destination: Rome (Forum, Colosseum, catacombs, temples)
|
||||
- Time: Approximate date
|
||||
- Spiritual context: Roman gods (Jupiter, Mars, Vesta), emperor worship, Stoic philosophy (Seneca, Marcus Aurelius), mystery cults (Mithras, Isis), early Christianity (if post-33 AD)
|
||||
- Who's there: Senators, philosophers, priests, augurs, vestals, gladiators, Christians (if applicable)
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "Rome"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
india:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested India: "the-users-response"
|
||||
|
||||
YOUR JOB: Generate briefing for India during requested time:
|
||||
|
||||
1. Determine time period (or default to 500 BC if unclear):
|
||||
- ~1500-500 BC: Vedic period, early Hinduism, Upanishads, Brahmins
|
||||
- ~563-483 BC: Buddha's lifetime, Buddhism emerging
|
||||
- ~500 BC-0: Buddhism spreading, Mauryan Empire, Ashoka promotes Buddhism
|
||||
- ~0-313 AD: Classical period, Hindu revival, Buddhist universities (Nalanda), Mahayana Buddhism
|
||||
|
||||
2. Provide briefing:
|
||||
- Destination: Varanasi, Bodh Gaya, monasteries, temples, forests
|
||||
- Time: Approximate date
|
||||
- Spiritual context: Hinduism (Brahma, Vishnu, Shiva, karma, reincarnation), Buddhism (monks, meditation, sutras), Jainism, yoga, gurus, ascetics
|
||||
- Who's there: Buddhist monks, Hindu priests, yogis, gurus, pilgrims, seekers
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "India"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
china:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested China: "the-users-response"
|
||||
|
||||
YOUR JOB: Generate briefing for China during requested time:
|
||||
|
||||
1. Determine time period (or default to 500 BC if unclear):
|
||||
- ~551-479 BC: Confucius lifetime, ethical philosophy
|
||||
- ~500-221 BC: Warring States, Laozi, Taoism, Hundred Schools of Thought
|
||||
- ~221 BC-220 AD: Qin/Han dynasties, Confucianism official, Taoism popular
|
||||
- ~220-313 AD: Buddhism arriving from India, Three Kingdoms
|
||||
|
||||
2. Provide briefing:
|
||||
- Destination: Courts, temples, mountains (Taoist retreats), cities
|
||||
- Time: Approximate date
|
||||
- Spiritual context: Confucianism (virtue, filial piety, social harmony), Taoism (Tao, wu wei, immortality, nature), ancestor worship, divination (I Ching)
|
||||
- Who's there: Confucian scholars, Taoist hermits, court philosophers, emperors, sages
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "China"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
persia:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested Persia: "the-users-response"
|
||||
|
||||
YOUR JOB: Generate briefing for Persia during requested time:
|
||||
|
||||
1. Determine time period (or default to 500 BC if unclear):
|
||||
- ~1500-600 BC: Early Iranian religion, Zoroaster (~628-551 BC)
|
||||
- ~550-330 BC: Achaemenid Empire, Zoroastrianism official, magi, fire temples
|
||||
- ~330-224 AD: Parthian period, continued Zoroastrianism, Jewish communities
|
||||
- ~224-313 AD: Sasanian rise, Zoroastrian revival
|
||||
|
||||
2. Provide briefing:
|
||||
- Destination: Persepolis, fire temples, magi schools
|
||||
- Time: Approximate date
|
||||
- Spiritual context: Zoroastrianism (Ahura Mazda vs Angra Mainyu, fire worship, dualism, magi priests), Jewish exile communities (if 586-538 BC)
|
||||
- Who's there: Magi (Zoroastrian priests), kings, fire keepers, exiled Jews (if applicable)
|
||||
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "Persia"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
other_world:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User requested other location: "the-users-response"
|
||||
|
||||
YOUR JOB: Generate briefing for their requested location during biblical timeline:
|
||||
|
||||
Examples:
|
||||
- Arabia: Trade routes, early monotheism, tribal religions
|
||||
- Egypt (non-biblical context): Pharaohs, Egyptian gods (Ra, Osiris, Isis), temples, pyramids
|
||||
- Ethiopia/Nubia: Ancient kingdoms, Egyptian influence, local religions
|
||||
- Britain/Gaul: Celtic druids, tribal spirituality
|
||||
- North Africa: Carthage, Phoenician gods, Punic culture
|
||||
|
||||
1. Determine location and time from their request
|
||||
2. Provide briefing similar to other regions
|
||||
3. End with: "⚡ Time travel initiated!"
|
||||
|
||||
Use metadata.language.
|
||||
metadata_add:
|
||||
current_region: "Other World"
|
||||
current_era: "the-users-response"
|
||||
epochs_visited: "n+1"
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
end:
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
|
||||
unclear:
|
||||
content_blocks:
|
||||
- "I'm not sure where/when you want to go. Can you be more specific?"
|
||||
- "Examples: '30 AD Greece', 'Moses', '500 BC India', 'Socrates', 'Jesus', 'Rome during Paul's time'"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
|
||||
# ============================================================================
|
||||
# EXPLORATION - OPEN-ENDED NPC INTERACTION
|
||||
# ============================================================================
|
||||
- section_id: "exploration"
|
||||
title: "Exploration"
|
||||
steps:
|
||||
- step_id: "who_to_meet"
|
||||
title: "Who to Meet"
|
||||
question: "Who would you like to meet here? (Or type 'EXPLORE' to look around, 'LEAVE' to travel elsewhere)"
|
||||
tokens_for_ai: |
|
||||
User choosing who to meet in metadata.current_region (metadata.current_era).
|
||||
|
||||
This is COMPLETELY OPEN-ENDED and GEOGRAPHY-AWARE. They can request:
|
||||
|
||||
BIBLICAL LANDS:
|
||||
- Biblical figures: Moses, Jesus, David, prophets, apostles, Adam, Eve
|
||||
- Types: slave, priest, shepherd, fisherman, Pharisee, Roman soldier
|
||||
|
||||
GREECE:
|
||||
- Philosophers: Socrates, Plato, Aristotle, Stoics, Epicureans
|
||||
- Religious: Mystery cult priest, oracle at Delphi, priestess
|
||||
- Types: philosopher, citizen, slave, athlete
|
||||
|
||||
ROME:
|
||||
- Philosophers: Seneca, Marcus Aurelius, Cicero
|
||||
- Religious: Vestal virgin, augur, priest of Jupiter, magi
|
||||
- Types: senator, gladiator, soldier, merchant, Christian (if applicable)
|
||||
|
||||
INDIA:
|
||||
- Spiritual: Buddhist monk, Hindu guru, yogi, Brahmin priest
|
||||
- Historical: Ashoka (if ~250 BC), teachers, ascetics
|
||||
|
||||
CHINA:
|
||||
- Philosophers: Confucius, Laozi, Mencius, Zhuangzi
|
||||
- Spiritual: Taoist hermit, Confucian scholar, court sage
|
||||
|
||||
PERSIA:
|
||||
- Religious: Zoroastrian magi, fire temple priest
|
||||
- Historical: Kings (Cyrus, Darius, Xerxes), exiled Jews (if applicable)
|
||||
|
||||
Categorize as:
|
||||
- 'meet_someone' if they name specific person or type
|
||||
- 'explore' if EXPLORE, look around, see the place
|
||||
- 'leave' if LEAVE, go elsewhere, new place
|
||||
- 'new_time' if they want different time period
|
||||
buckets: [meet_someone, explore, leave, new_time]
|
||||
transitions:
|
||||
meet_someone:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User wants to meet: "the-users-response"
|
||||
|
||||
Location: metadata.current_region
|
||||
Era: metadata.current_era
|
||||
Language: metadata.language
|
||||
|
||||
YOUR JOB:
|
||||
1. Determine if this person/type exists in this region during this time
|
||||
2. Consider geography: Greek philosophers in Greece, Buddhist monks in India, magi in Persia, biblical figures in biblical lands
|
||||
3. If person exists: Describe meeting them (2-3 sentences) - appearance, setting, first impression
|
||||
4. If person doesn't exist yet/there: Politely explain when/where they can be found, offer alternative
|
||||
5. Be culturally and spiritually respectful of all traditions
|
||||
|
||||
ACCURACY REQUIREMENTS:
|
||||
- Biblical lands: Maintain Temple status accuracy
|
||||
- Greece: Verify philosopher lifespans (Socrates 470-399 BC, Plato 428-348 BC, etc.)
|
||||
- India: Don't place Buddha after his death (483 BC), but his followers exist afterward
|
||||
- China: Confucius 551-479 BC, Laozi ~6th century BC
|
||||
- Rome: Different figures for Republic vs Empire periods
|
||||
|
||||
Use metadata.language for response.
|
||||
metadata_add:
|
||||
current_npc: "the-users-response"
|
||||
people_met: "n+1"
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
explore:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
User wants to explore/look around.
|
||||
|
||||
Location: metadata.current_region
|
||||
Era: metadata.current_era
|
||||
|
||||
Describe what they see (3-5 sentences):
|
||||
|
||||
BIBLICAL LANDS:
|
||||
- Geography (desert, hills, Sea of Galilee, etc.)
|
||||
- Temple status (CRITICAL: none before Solomon, First Temple 970-586 BC, Second Temple 516 BC-70 AD, none after 70 AD)
|
||||
- Buildings (tents, stone houses, synagogues, etc.)
|
||||
- Activity (worship, trading, daily life)
|
||||
- People present (specific to era)
|
||||
|
||||
GREECE:
|
||||
- Geography (Acropolis, agora, mountains, Mediterranean)
|
||||
- Buildings (temples to Zeus/Athena/Apollo, Academy, Lyceum, Stoa)
|
||||
- Activity (philosophy debates, Olympics, mystery rites, theater)
|
||||
- People (philosophers, citizens, slaves, priestesses)
|
||||
|
||||
ROME:
|
||||
- Geography (Seven Hills, Tiber River, Forum, Colosseum if applicable)
|
||||
- Buildings (temples, Senate, aqueducts, baths, catacombs if Christian era)
|
||||
- Activity (gladiator fights, politics, emperor worship, philosophy)
|
||||
- People (senators, soldiers, philosophers, Christians if applicable)
|
||||
|
||||
INDIA:
|
||||
- Geography (Ganges River, Himalayas, forests, monasteries)
|
||||
- Buildings (temples, stupas, ashrams, meditation caves)
|
||||
- Activity (meditation, puja, pilgrimage, teaching)
|
||||
- People (monks, gurus, pilgrims, yogis)
|
||||
|
||||
CHINA:
|
||||
- Geography (Yellow River, mountains, imperial palace, temples)
|
||||
- Buildings (Confucian temples, Taoist retreats, palace)
|
||||
- Activity (rituals, philosophy debates, calligraphy, ancestor worship)
|
||||
- People (scholars, emperors, hermits, officials)
|
||||
|
||||
PERSIA:
|
||||
- Geography (Persepolis, fire temples, mountains, palaces)
|
||||
- Buildings (fire temples, royal palaces, magi schools)
|
||||
- Activity (fire worship, royal courts, Zoroastrian rites)
|
||||
- People (magi, kings, fire keepers, possibly exiled Jews)
|
||||
|
||||
End by asking who they'd like to meet.
|
||||
|
||||
Use metadata.language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
leave:
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
|
||||
new_time:
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
|
||||
- step_id: "conversation"
|
||||
title: "Conversation"
|
||||
question: "What would you like to say or ask?"
|
||||
tokens_for_ai: |
|
||||
User conversing with metadata.current_npc in metadata.current_region (metadata.current_era).
|
||||
|
||||
Categorize as:
|
||||
- 'spiritual' for questions about faith, God(s), enlightenment, meaning, afterlife, spiritual practices
|
||||
- 'philosophical' for questions about ethics, wisdom, virtue, the good life, truth, knowledge
|
||||
- 'historical' for questions about events, politics, wars, daily life, context
|
||||
- 'personal' for questions about the NPC's life, experiences, journey
|
||||
- 'continue' for statements, comments, or general conversation
|
||||
- 'done' if goodbye, done talking, want to leave
|
||||
- 'someone_else' if they want to meet someone else
|
||||
- 'new_time' if they want to go to different era
|
||||
- 'language_change' for language change requests
|
||||
buckets: [spiritual, philosophical, historical, personal, continue, done, someone_else, new_time, language_change]
|
||||
transitions:
|
||||
spiritual:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Respond IN CHARACTER as metadata.current_npc in metadata.current_region.
|
||||
|
||||
Context:
|
||||
- Region: metadata.current_region
|
||||
- Era: metadata.current_era
|
||||
- Language: metadata.language
|
||||
|
||||
Answer their spiritual/religious question authentically based on their tradition:
|
||||
|
||||
BIBLICAL LANDS:
|
||||
- Reference YHWH, biblical scripture, prophecy, covenant, Messiah
|
||||
- Temple status awareness (none/First/Second/destroyed)
|
||||
- Show Jewish/Christian faith perspective
|
||||
|
||||
GREECE:
|
||||
- Reference Greek gods (Zeus, Athena, Apollo), mystery religions, philosophical theology
|
||||
- Discuss fate, divine will, oracle prophecies, the Forms (if Platonist)
|
||||
- Show reverence for gods or rational skepticism (if philosopher)
|
||||
|
||||
ROME:
|
||||
- Reference Roman gods (Jupiter, Mars, Vesta), emperor as divine, Stoic theology
|
||||
- Discuss virtue, logos, providence, duty to gods and state
|
||||
- Show civic piety or philosophical spirituality
|
||||
|
||||
INDIA:
|
||||
- Reference Brahma/Vishnu/Shiva (Hindu) or Buddha/dharma (Buddhist)
|
||||
- Discuss karma, reincarnation, moksha/nirvana, meditation, yoga
|
||||
- Show devotion or detachment as appropriate
|
||||
|
||||
CHINA:
|
||||
- Reference Tian (Heaven), Tao, ancestors, cosmic harmony
|
||||
- Discuss virtue (ren), filial piety, wu wei, yin-yang, harmony
|
||||
- Show Confucian order or Taoist spontaneity
|
||||
|
||||
PERSIA:
|
||||
- Reference Ahura Mazda vs Angra Mainyu (Zoroastrianism)
|
||||
- Discuss fire worship, dualism, truth vs lies, final judgment
|
||||
- Show devotion to truth and purity
|
||||
|
||||
Keep response conversational (not preachy or essay-length).
|
||||
Be respectful of all traditions.
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
philosophical:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Respond IN CHARACTER as metadata.current_npc.
|
||||
|
||||
Answer their philosophical question based on their tradition:
|
||||
- Greek: Socratic method, Platonic Forms, Aristotelian logic, Stoic virtue, Epicurean pleasure
|
||||
- Chinese: Confucian virtue, Taoist naturalness, moral cultivation
|
||||
- Roman: Stoic duty, Ciceronian rhetoric, practical wisdom
|
||||
- Indian: Dharma, right action, spiritual wisdom
|
||||
- Biblical: Wisdom literature, moral law, divine will
|
||||
|
||||
Keep conversational.
|
||||
Use metadata.language.
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
historical:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Respond IN CHARACTER as metadata.current_npc.
|
||||
|
||||
Answer their historical question accurately:
|
||||
- Events happening in their time
|
||||
- Political context (empires, rulers, wars)
|
||||
- Daily life details
|
||||
- Buildings and geography (Temple status in biblical lands!)
|
||||
|
||||
Use metadata.language.
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
personal:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Respond IN CHARACTER as metadata.current_npc.
|
||||
|
||||
Share personal experience, feelings, life story.
|
||||
Be authentic to the time period and person's situation.
|
||||
Show their humanity and spiritual journey.
|
||||
|
||||
Use metadata.language.
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
continue:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Respond IN CHARACTER as metadata.current_npc.
|
||||
|
||||
Respond naturally to their statement.
|
||||
Continue the conversation.
|
||||
Show personality and engagement.
|
||||
|
||||
Use metadata.language.
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
done:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
The NPC bids them farewell (brief - 1-2 sentences).
|
||||
Appropriate to their culture (Greek formality, Chinese respect, biblical blessing, etc.)
|
||||
|
||||
Use metadata.language.
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
someone_else:
|
||||
content_blocks:
|
||||
- "Ending current conversation..."
|
||||
next_section_and_step: "exploration:who_to_meet"
|
||||
|
||||
new_time:
|
||||
content_blocks:
|
||||
- "Returning to time machine..."
|
||||
next_section_and_step: "time_machine:destination_input"
|
||||
|
||||
language_change:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "exploration:conversation"
|
||||
|
||||
# ============================================================================
|
||||
# CONCLUSION
|
||||
# ============================================================================
|
||||
- section_id: "conclusion"
|
||||
title: "Journey's End"
|
||||
steps:
|
||||
- step_id: "reflection"
|
||||
title: "Reflection"
|
||||
question: "What was the most meaningful moment from your journey through Biblical history?"
|
||||
tokens_for_ai: |
|
||||
User reflecting on their experience.
|
||||
|
||||
Categorize as 'reflect' for any response.
|
||||
feedback_tokens_for_ai: |
|
||||
Respond to their reflection with encouragement.
|
||||
|
||||
- Acknowledge what they found meaningful
|
||||
- Connect to biblical themes
|
||||
- Encourage further Bible study
|
||||
- Thank them for the journey
|
||||
|
||||
Use metadata.language.
|
||||
|
||||
End with blessing and invitation to return.
|
||||
buckets: [reflect]
|
||||
transitions:
|
||||
reflect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide warm, encouraging response about their spiritual journey."
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: "conclusion:goodbye"
|
||||
|
||||
- step_id: "goodbye"
|
||||
title: "Farewell"
|
||||
content_blocks:
|
||||
- "# Thank You for Traveling Through Biblical History"
|
||||
- ""
|
||||
- "From Eden to persecution, from Paradise to martyrdom—"
|
||||
- "you've witnessed God's redemptive story unfold."
|
||||
- ""
|
||||
- "The time machine is always here when you want to return. ⏳"
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_0"
|
||||
feedback_model: "MODEL_0"
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
Test activity for v2.0 features.
|
||||
Evaluate responses generously - this is just a demo!
|
||||
|
||||
sections:
|
||||
- section_id: intro
|
||||
title: V2.0 Features Demo
|
||||
steps:
|
||||
# Test: Template variables in content blocks
|
||||
- step_id: welcome
|
||||
title: Welcome with Templates
|
||||
content_blocks:
|
||||
- "# Welcome to OpenCompletion V2.0! 🎉"
|
||||
- ""
|
||||
- "This activity demonstrates all new v2.0 features."
|
||||
- "Current section: {{current_section}}"
|
||||
- "Current step: {{current_step}}"
|
||||
question: "What's your name?"
|
||||
tokens_for_ai: |
|
||||
Categorize as 'name_provided' if they give a name.
|
||||
Otherwise 'off_topic'.
|
||||
buckets: [name_provided, off_topic]
|
||||
transitions:
|
||||
name_provided:
|
||||
content_blocks:
|
||||
- "Great to meet you!"
|
||||
metadata_add:
|
||||
player_name: "the-users-response"
|
||||
score: "n+1"
|
||||
next_section_and_step: "templates:test_templates"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Please tell me your name."
|
||||
next_section_and_step: "intro:welcome"
|
||||
|
||||
# Section: Template Variables
|
||||
- section_id: templates
|
||||
title: Template Variables Test
|
||||
steps:
|
||||
- step_id: test_templates
|
||||
title: Testing Templates
|
||||
content_blocks:
|
||||
- "# Template Variables Test"
|
||||
- ""
|
||||
- "Welcome back, {{metadata.player_name}}!"
|
||||
- "Your score: {{metadata.score}}"
|
||||
- "Attempt {{current_attempt}} of {{max_attempts}}"
|
||||
- "Attempts remaining: {{attempts_remaining}}"
|
||||
question: "Ready to test conditional content? (yes/no)"
|
||||
tokens_for_ai: "Categorize as 'yes' or 'no' based on their response."
|
||||
buckets: [yes, no]
|
||||
transitions:
|
||||
yes:
|
||||
content_blocks:
|
||||
- "Excellent!"
|
||||
next_section_and_step: "conditionals:test_conditional_blocks"
|
||||
no:
|
||||
content_blocks:
|
||||
- "Take your time!"
|
||||
next_section_and_step: "templates:test_templates"
|
||||
|
||||
# Section: Conditional Content Blocks
|
||||
- section_id: conditionals
|
||||
title: Conditional Content Test
|
||||
steps:
|
||||
- step_id: test_conditional_blocks
|
||||
title: Conditional Content Blocks
|
||||
content_blocks:
|
||||
# Always shown
|
||||
- "# Conditional Content Test"
|
||||
- ""
|
||||
# Conditional - only if score >= 1
|
||||
- text: "🌟 You have points! Great job!"
|
||||
show_if:
|
||||
score_gte: 1
|
||||
# Conditional - only if score < 1
|
||||
- text: "Start earning points!"
|
||||
show_if:
|
||||
score_lt: 1
|
||||
# Conditional - personalized
|
||||
- text: "Hello {{metadata.player_name}}, let's continue!"
|
||||
show_if:
|
||||
player_name_exists: true
|
||||
question: "What's 5 + 3?"
|
||||
tokens_for_ai: "Categorize as 'correct' if 8 or eight, otherwise 'incorrect'."
|
||||
buckets: [correct, incorrect]
|
||||
|
||||
# Progressive hints test
|
||||
hints:
|
||||
- attempt: 1
|
||||
text: "💡 Hint: It's less than 10"
|
||||
counts_as_attempt: false
|
||||
- attempt: 2
|
||||
text: "💡 Strong Hint: 5 + 3 = ?"
|
||||
counts_as_attempt: false
|
||||
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Perfect! ✅"
|
||||
metadata_add:
|
||||
score: "n+5"
|
||||
next_section_and_step: "weighted_random:test_weighted"
|
||||
incorrect:
|
||||
content_blocks:
|
||||
- "Try again!"
|
||||
next_section_and_step: "conditionals:test_conditional_blocks"
|
||||
|
||||
# Section: Weighted Random
|
||||
- section_id: weighted_random
|
||||
title: Weighted Random Test
|
||||
steps:
|
||||
- step_id: test_weighted
|
||||
title: Weighted Random Selection
|
||||
content_blocks:
|
||||
- "# Weighted Random Test"
|
||||
- ""
|
||||
- "Let's test weighted random selection!"
|
||||
question: "Roll the dice! (type 'roll')"
|
||||
tokens_for_ai: "Categorize as 'roll'."
|
||||
buckets: [roll]
|
||||
transitions:
|
||||
roll:
|
||||
metadata_weighted_random:
|
||||
loot:
|
||||
- value: "common_item"
|
||||
weight: 70
|
||||
- value: "rare_item"
|
||||
weight: 25
|
||||
- value: "legendary_item"
|
||||
weight: 5
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
The user found: {{metadata.loot}}
|
||||
If common_item: "You found a Common Item"
|
||||
If rare_item: "You found a Rare Item! 🌟"
|
||||
If legendary_item: "LEGENDARY ITEM FOUND! 🏆"
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "conditional_nav:test_nav"
|
||||
|
||||
# Section: Conditional Navigation
|
||||
- section_id: conditional_nav
|
||||
title: Conditional Navigation Test
|
||||
steps:
|
||||
- step_id: test_nav
|
||||
title: Conditional Navigation
|
||||
content_blocks:
|
||||
- "# Conditional Navigation Test"
|
||||
- ""
|
||||
- "Your current score: {{metadata.score}}"
|
||||
- ""
|
||||
- "Based on your score, you'll be routed to different paths!"
|
||||
question: "Continue? (yes)"
|
||||
tokens_for_ai: "Categorize as 'continue'."
|
||||
buckets: [continue]
|
||||
transitions:
|
||||
continue:
|
||||
# Conditional navigation based on score
|
||||
next_section_and_step:
|
||||
- if:
|
||||
score_gte: 10
|
||||
goto: "endings:high_score"
|
||||
- elif:
|
||||
score_gte: 5
|
||||
goto: "endings:medium_score"
|
||||
- else:
|
||||
goto: "endings:low_score"
|
||||
|
||||
# Section: Different Endings
|
||||
- section_id: endings
|
||||
title: Endings
|
||||
steps:
|
||||
- step_id: high_score
|
||||
title: High Score Ending
|
||||
content_blocks:
|
||||
- "# 🏆 AMAZING! High Score!"
|
||||
- ""
|
||||
- "{{metadata.player_name}}, you scored {{metadata.score}} points!"
|
||||
- ""
|
||||
- "You're a V2.0 features master!"
|
||||
|
||||
- step_id: medium_score
|
||||
title: Medium Score Ending
|
||||
content_blocks:
|
||||
- "# 🌟 GOOD JOB! Medium Score!"
|
||||
- ""
|
||||
- "{{metadata.player_name}}, you scored {{metadata.score}} points!"
|
||||
- ""
|
||||
- "Great understanding of V2.0 features!"
|
||||
|
||||
- step_id: low_score
|
||||
title: Low Score Ending
|
||||
content_blocks:
|
||||
- "# ✨ Good Start!"
|
||||
- ""
|
||||
- "{{metadata.player_name}}, you scored {{metadata.score}} points!"
|
||||
- ""
|
||||
- "You've learned the basics of V2.0 features!"
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to AI"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Understanding AI"
|
||||
content_blocks:
|
||||
- "Welcome to the introduction to AI."
|
||||
- "In this section, we will cover the basics of AI."
|
||||
tokens_for_ai: "Explain the basics of AI to the user in a friendly and engaging manner."
|
||||
question: "What do you understand by Artificial Intelligence?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of AI."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of AI. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on AI."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of AI in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Applications of AI"
|
||||
content_blocks:
|
||||
- "Now that you understand the basics of AI, let's explore its applications."
|
||||
- "AI is used in various fields such as healthcare, finance, and transportation."
|
||||
tokens_for_ai: "Explain the applications of AI in different fields in a friendly and engaging manner."
|
||||
question: "Can you name a few applications of AI?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You have identified some key applications of AI."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of AI applications. Let's explore more."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on AI applications."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of AI applications in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The end of AI"
|
||||
content_blocks:
|
||||
- "The end of AI."
|
||||
|
|
@ -1,438 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_0"
|
||||
title: "Introduction"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "Welcome to the GNU Manifesto course! 👋"
|
||||
- "You will learn about the GNU Manifesto and its significance."
|
||||
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to The GNU Manifesto"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is The GNU Manifesto?"
|
||||
content_blocks:
|
||||
- "<img src='https://www.gnu.org/graphics/heckert_gnu.transp.small.png'>"
|
||||
- "Welcome to the GNU Manifesto course! 👋"
|
||||
- "The GNU Manifesto was written by Richard Stallman in 1985 to ask for support in developing the GNU operating system."
|
||||
- "Think about why someone might want to create a free operating system. Consider issues like software freedom, collaboration, and accessibility."
|
||||
tokens_for_ai: "Guide the student to think about the reasons for creating a free operating system. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think Richard Stallman wanted to create a free operating system? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of why Richard Stallman wanted to create a free operating system. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. What do you think are some reasons someone might want a free operating system? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the reasons for creating a free operating system. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the reasons for creating a free operating system in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of The GNU Manifesto"
|
||||
content_blocks:
|
||||
- "The GNU Manifesto is important because it laid the foundation for the Free Software Movement."
|
||||
- "It emphasizes the importance of software freedom, collaboration, and user rights."
|
||||
- "Think about how having free software might benefit users and developers. Consider aspects like cost, accessibility, and innovation."
|
||||
tokens_for_ai: "Guide the student to think about the benefits of free software. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think free software benefits users and developers? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the benefits of free software. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think free software might help users and developers? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the benefits of free software. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the benefits of free software in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Key Concepts of The GNU Manifesto"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is GNU?"
|
||||
content_blocks:
|
||||
- "GNU stands for 'Gnu's Not Unix' and is a free Unix-compatible software system."
|
||||
- "Richard Stallman and other volunteers are developing GNU to provide a free alternative to proprietary Unix systems."
|
||||
- "Think about why it might be important for GNU to be compatible with Unix. Consider aspects like user familiarity, software compatibility, and ease of adoption."
|
||||
tokens_for_ai: "Guide the student to think about the importance of GNU being compatible with Unix. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think it is important for GNU to be compatible with Unix? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of GNU being compatible with Unix. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. Why do you think compatibility with Unix is important for GNU? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of GNU being compatible with Unix. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the importance of GNU being compatible with Unix in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Why GNU Will Be Free"
|
||||
content_blocks:
|
||||
- "GNU is not in the public domain, but it will be free for everyone to use, modify, and redistribute."
|
||||
- "No distributor will be allowed to restrict its further redistribution, ensuring that all versions of GNU remain free."
|
||||
- "Think about why it might be important for GNU to remain free. Consider aspects like user rights, collaboration, and innovation."
|
||||
tokens_for_ai: "Guide the student to think about the importance of GNU remaining free. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think it is important for GNU to remain free? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of GNU remaining free. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. Why do you think it's important for GNU to remain free? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of GNU remaining free. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the importance of GNU remaining free in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Contributing to GNU"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "How to Contribute"
|
||||
content_blocks:
|
||||
- "There are many ways to contribute to the GNU Project, including donating money, programs, and work."
|
||||
- "Think about why it might be important for people to contribute to the GNU Project. Consider aspects like community, collaboration, and shared goals."
|
||||
tokens_for_ai: "Guide the student to think about the importance of contributing to the GNU Project. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think it is important for people to contribute to the GNU Project? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of contributing to the GNU Project. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. Why do you think contributing to the GNU Project is important? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of contributing to the GNU Project. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the importance of contributing to the GNU Project in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Ways to Contribute"
|
||||
content_blocks:
|
||||
- "You can contribute to the GNU Project by writing code, fixing bugs, improving documentation, and more."
|
||||
- "Think about how your skills and interests might align with the needs of the GNU Project. How can you make a meaningful contribution?"
|
||||
tokens_for_ai: "Guide the student to think about how they can contribute to the GNU Project based on their skills and interests. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think you can contribute to the GNU Project based on your skills and interests? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You have a good idea of how you can contribute to the GNU Project. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think you can contribute to the GNU Project with your skills? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on how you can contribute to the GNU Project. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of how they can contribute to the GNU Project in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Legacy of The GNU Manifesto"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Impact on Software Development"
|
||||
content_blocks:
|
||||
- "The GNU Manifesto has had a profound impact on software development, promoting the principles of free software and user rights."
|
||||
- "Think about how the principles of the GNU Manifesto might have influenced modern software development practices. Consider aspects like open source, collaboration, and innovation."
|
||||
tokens_for_ai: "Guide the student to think about the impact of the GNU Manifesto on modern software development. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the principles of the GNU Manifesto have influenced modern software development practices? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the impact of the GNU Manifesto on modern software development. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think the GNU Manifesto has influenced software development? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the impact of the GNU Manifesto. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the impact of the GNU Manifesto in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Future of Free Software"
|
||||
content_blocks:
|
||||
- "The principles of the GNU Manifesto continue to inspire the Free Software Movement and the development of free software."
|
||||
- "Think about how the principles of free software might shape the future of technology. Consider aspects like user rights, innovation, and collaboration."
|
||||
tokens_for_ai: "Guide the student to think about the future of free software and its impact on technology. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the principles of free software will shape the future of technology? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand how the principles of free software might shape the future of technology. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think free software will shape technology's future? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the future of free software. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the future of free software in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the GNU Manifesto course! 🎉"
|
||||
- "You have learned about the key concepts, principles, and impact of the GNU Manifesto."
|
||||
- "This knowledge will help you understand the importance of software freedom and the Free Software Movement."
|
||||
- "We are proud of your dedication and hard work. Well done! 🌟"
|
||||
|
|
@ -1,368 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to the Miracles of Jesus"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Who is Jesus?"
|
||||
content_blocks:
|
||||
- "Welcome to the **Miracles of Jesus** course!"
|
||||
- "Jesus is a central figure in Christianity, known for his teachings, compassion, and miraculous acts."
|
||||
tokens_for_ai: "Explain who Jesus is in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "**What do you know about Jesus?**"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of who Jesus is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of who Jesus is. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on who Jesus is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of who Jesus is in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of Miracles"
|
||||
content_blocks:
|
||||
- "Miracles are extraordinary events that demonstrate divine intervention in the world."
|
||||
- "The miracles performed by Jesus are significant because they reveal his divine nature and compassion for humanity."
|
||||
tokens_for_ai: "Explain the importance of miracles in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "**Why are the miracles of Jesus important?**"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of the miracles of Jesus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of the miracles of Jesus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of the miracles of Jesus in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Miracles of Healing"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Healing the Blind Man"
|
||||
content_blocks:
|
||||
- "One of Jesus' miracles was healing a man who was born blind."
|
||||
- "Jesus made mud with his saliva, put it on the man's eyes, and told him to wash in the Pool of Siloam. The man washed and was able to see."
|
||||
tokens_for_ai: "Explain the miracle of healing the blind man in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of healing the blind man?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about the miracle of healing the blind man."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of healing the blind man."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of healing the blind man in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Healing the Leper"
|
||||
content_blocks:
|
||||
- "Another miracle of Jesus was healing a man with leprosy."
|
||||
- "Jesus touched the man and said, 'Be clean!' Immediately, the leprosy left him, and he was healed."
|
||||
tokens_for_ai: "Explain the miracle of healing the leper in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of healing the leper?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about the miracle of healing the leper."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of healing the leper."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of healing the leper in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Miracles of Provision"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Feeding the 5,000"
|
||||
content_blocks:
|
||||
- "One of Jesus' most famous miracles is feeding 5,000 people with just five loaves of bread and two fish."
|
||||
- "Jesus blessed the food, broke it, and distributed it to the crowd. Everyone ate and was satisfied, and there were twelve baskets of leftovers."
|
||||
tokens_for_ai: "Explain the miracle of feeding the 5,000 in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of feeding the 5,000?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about the miracle of feeding the 5,000."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of feeding the 5,000."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of feeding the 5,000 in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Turning Water into Wine"
|
||||
content_blocks:
|
||||
- "Jesus' first recorded miracle was turning water into wine at a wedding in Cana."
|
||||
- "When the wine ran out, Jesus instructed the servants to fill six stone jars with water. He then turned the water into wine, which was of the highest quality."
|
||||
tokens_for_ai: "Explain the miracle of turning water into wine in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of turning water into wine?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about the miracle of turning water into wine."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of turning water into wine."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of turning water into wine in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Miracles of Nature"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Calming the Storm"
|
||||
content_blocks:
|
||||
- "One of Jesus' miracles involved calming a storm while he and his disciples were on a boat."
|
||||
- "Jesus rebuked the wind and said to the waves, 'Quiet! Be still!' The wind died down, and it was completely calm."
|
||||
tokens_for_ai: "Explain the miracle of calming the storm in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of calming the storm?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about the miracle of calming the storm."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of calming the storm."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of calming the storm in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Walking on Water"
|
||||
content_blocks:
|
||||
- "Another miracle of Jesus was walking on water."
|
||||
- "Jesus walked on the Sea of Galilee to reach his disciples who were in a boat. When they saw him, they were terrified, but Jesus said, 'Take courage! It is I. Don't be afraid.'"
|
||||
tokens_for_ai: "Explain the miracle of walking on water in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of walking on water?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about the miracle of walking on water."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of walking on water."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of walking on water in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Miracles of Resurrection"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Raising Lazarus"
|
||||
content_blocks:
|
||||
- "One of Jesus' most powerful miracles was raising Lazarus from the dead."
|
||||
- "Lazarus had been dead for four days when Jesus arrived. Jesus called out, 'Lazarus, come out!' and Lazarus came out of the tomb, alive."
|
||||
tokens_for_ai: "Explain the miracle of raising Lazarus in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of raising Lazarus?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about the miracle of raising Lazarus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of raising Lazarus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of raising Lazarus in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Resurrection of Jesus"
|
||||
content_blocks:
|
||||
- "The most significant miracle in Christianity is the resurrection of Jesus."
|
||||
- "After being crucified and buried, Jesus rose from the dead on the third day. His resurrection is celebrated as Easter and is the foundation of Christian faith."
|
||||
tokens_for_ai: "Explain the miracle of the resurrection of Jesus in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the miracle of the resurrection of Jesus?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about the miracle of the resurrection of Jesus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the miracle. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the miracle of the resurrection of Jesus."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the resurrection of Jesus in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Miracles of Jesus course!"
|
||||
- "You have learned about the various miracles performed by Jesus, including healing, provision, nature, and resurrection."
|
||||
- "These miracles demonstrate Jesus' divine power and compassion for humanity."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
||||
|
|
@ -1,580 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is the Revolutionary War?"
|
||||
content_blocks:
|
||||
- "Welcome to the American Revolutionary War course!"
|
||||
- "The American Revolutionary War, also known as the American War of Independence, was a conflict between Great Britain and its thirteen colonies in North America."
|
||||
tokens_for_ai: "Explain what the American Revolutionary War is in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you know about the American Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of the American Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Revolutionary War. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Revolutionary War in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of the Revolutionary War"
|
||||
content_blocks:
|
||||
- "The Revolutionary War was important because it led to the independence of the United States from British rule."
|
||||
- "It also established the principles of liberty, democracy, and self-governance."
|
||||
tokens_for_ai: "Explain the importance of the American Revolutionary War in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is the American Revolutionary War important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of the American Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of the Revolutionary War in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Causes of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Taxation Without Representation"
|
||||
content_blocks:
|
||||
- "One of the main causes of the Revolutionary War was the issue of 'taxation without representation.'"
|
||||
- "The British government imposed taxes on the American colonies without giving them representation in Parliament."
|
||||
tokens_for_ai: "Explain the concept of 'taxation without representation' and its role in causing the Revolutionary War in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is 'taxation without representation' and how did it contribute to the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the concept of 'taxation without representation' and its role in the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of 'taxation without representation.' Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on 'taxation without representation.'"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of 'taxation without representation' in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Intolerable Acts"
|
||||
content_blocks:
|
||||
- "The Intolerable Acts were a series of punitive laws passed by the British Parliament in response to the Boston Tea Party."
|
||||
- "These acts further angered the American colonists and contributed to the outbreak of the Revolutionary War."
|
||||
tokens_for_ai: "Explain what the Intolerable Acts were and their role in causing the Revolutionary War in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What were the Intolerable Acts and how did they contribute to the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what the Intolerable Acts were and their role in the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Intolerable Acts. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Intolerable Acts."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Intolerable Acts in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Key Events of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Boston Tea Party"
|
||||
content_blocks:
|
||||
- "The Boston Tea Party was a political protest by the Sons of Liberty in Boston, Massachusetts, on December 16, 1773."
|
||||
- "American colonists, frustrated with British taxation, dumped 342 chests of British tea into the harbor."
|
||||
tokens_for_ai: "Explain the Boston Tea Party and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Boston Tea Party and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what the Boston Tea Party was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Boston Tea Party. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Boston Tea Party."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Boston Tea Party in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Battles of Lexington and Concord"
|
||||
content_blocks:
|
||||
- "The Battles of Lexington and Concord were the first military engagements of the American Revolutionary War."
|
||||
- "They were fought on April 19, 1775, in Middlesex County, Province of Massachusetts Bay."
|
||||
tokens_for_ai: "Explain the Battles of Lexington and Concord and their significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What were the Battles of Lexington and Concord and why were they significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what the Battles of Lexington and Concord were and their significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Battles of Lexington and Concord. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battles of Lexington and Concord."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Battles of Lexington and Concord in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Key Figures of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "George Washington"
|
||||
content_blocks:
|
||||
- "George Washington was the commander-in-chief of the Continental Army during the American Revolutionary War."
|
||||
- "He later became the first President of the United States."
|
||||
tokens_for_ai: "Explain who George Washington was and his role in the Revolutionary War in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Who was George Washington and what was his role in the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand who George Washington was and his role in the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of George Washington. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on George Washington."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of George Washington in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Thomas Jefferson"
|
||||
content_blocks:
|
||||
- "Thomas Jefferson was the principal author of the Declaration of Independence."
|
||||
- "He later became the third President of the United States."
|
||||
tokens_for_ai: "Explain who Thomas Jefferson was and his role in the Revolutionary War in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Who was Thomas Jefferson and what was his role in the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand who Thomas Jefferson was and his role in the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of Thomas Jefferson. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Thomas Jefferson."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Thomas Jefferson in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Major Battles of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Battle of Bunker Hill"
|
||||
content_blocks:
|
||||
- "The Battle of Bunker Hill was fought on June 17, 1775, during the early stages of the American Revolutionary War."
|
||||
- "Despite being a British victory, the battle demonstrated that the American forces could stand up to the British army."
|
||||
tokens_for_ai: "Explain the Battle of Bunker Hill and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Battle of Bunker Hill and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what the Battle of Bunker Hill was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Battle of Bunker Hill. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battle of Bunker Hill."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Battle of Bunker Hill in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Battle of Saratoga"
|
||||
content_blocks:
|
||||
- "The Battle of Saratoga was a turning point in the American Revolutionary War."
|
||||
- "Fought in 1777, it resulted in a decisive victory for the American forces and convinced France to join the war on the side of the Americans."
|
||||
tokens_for_ai: "Explain the Battle of Saratoga and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Battle of Saratoga and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what the Battle of Saratoga was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Battle of Saratoga. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battle of Saratoga."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Battle of Saratoga in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "The Declaration of Independence"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Drafting the Declaration"
|
||||
content_blocks:
|
||||
- "The Declaration of Independence was drafted by Thomas Jefferson and adopted by the Continental Congress on July 4, 1776."
|
||||
- "It declared the thirteen American colonies as independent states, free from British rule."
|
||||
tokens_for_ai: "Explain the drafting of the Declaration of Independence and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Declaration of Independence and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what the Declaration of Independence was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Declaration of Independence. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Declaration of Independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Key Principles of the Declaration"
|
||||
content_blocks:
|
||||
- "The Declaration of Independence outlined key principles such as equality, unalienable rights, and the right to alter or abolish government."
|
||||
- "It emphasized that all men are created equal and have the right to life, liberty, and the pursuit of happiness."
|
||||
tokens_for_ai: "Explain the key principles of the Declaration of Independence in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What are the key principles of the Declaration of Independence?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the key principles of the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the key principles. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the key principles of the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the key principles of the Declaration of Independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "The End of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Siege of Yorktown"
|
||||
content_blocks:
|
||||
- "The Siege of Yorktown was the last major battle of the American Revolutionary War."
|
||||
- "Fought in 1781, it resulted in the surrender of British General Cornwallis and effectively ended the war."
|
||||
tokens_for_ai: "Explain the Siege of Yorktown and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Siege of Yorktown and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what the Siege of Yorktown was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Siege of Yorktown. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Siege of Yorktown."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Siege of Yorktown in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Treaty of Paris"
|
||||
content_blocks:
|
||||
- "The Treaty of Paris was signed on September 3, 1783, and officially ended the American Revolutionary War."
|
||||
- "The treaty recognized the independence of the United States and established its borders."
|
||||
tokens_for_ai: "Explain the Treaty of Paris and its significance in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the Treaty of Paris and why was it significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what the Treaty of Paris was and its significance."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the Treaty of Paris. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Treaty of Paris."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Treaty of Paris in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_8"
|
||||
title: "Legacy of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Impact on the United States"
|
||||
content_blocks:
|
||||
- "The American Revolutionary War had a profound impact on the United States."
|
||||
- "It led to the establishment of a new nation based on principles of liberty, democracy, and self-governance."
|
||||
tokens_for_ai: "Explain the impact of the Revolutionary War on the United States in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the impact of the Revolutionary War on the United States?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the impact of the Revolutionary War on the United States."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the impact. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the impact of the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the impact of the Revolutionary War in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Influence on Other Nations"
|
||||
content_blocks:
|
||||
- "The American Revolutionary War inspired other nations to fight for their independence and adopt democratic principles."
|
||||
- "It had a significant influence on the French Revolution and other independence movements around the world."
|
||||
tokens_for_ai: "Explain the influence of the Revolutionary War on other nations in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How did the Revolutionary War influence other nations?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the influence of the Revolutionary War on other nations."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the influence. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the influence of the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the influence of the Revolutionary War in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_9"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the American Revolutionary War course!"
|
||||
- "You have learned about the causes, key events, major battles, important figures, and the legacy of the Revolutionary War."
|
||||
- "This knowledge will help you understand the foundations of the United States and the principles of liberty and democracy."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
|
@ -1,596 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is the Revolutionary War?"
|
||||
content_blocks:
|
||||
- "Welcome to the American Revolutionary War course!"
|
||||
- "The American Revolutionary War, also known as the American War of Independence, was a conflict between Great Britain and its thirteen colonies in North America."
|
||||
- "Think about why the colonies might have wanted to break away from British rule. Consider issues like governance, taxes, and representation."
|
||||
tokens_for_ai: "Guide the student to think about the reasons for the colonies wanting independence. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the American colonies wanted to break away from British rule?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of why the colonies wanted independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the reasons for independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the reasons for independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of the Revolutionary War"
|
||||
content_blocks:
|
||||
- "The Revolutionary War was important because it led to the independence of the United States from British rule."
|
||||
- "It also established the principles of liberty, democracy, and self-governance."
|
||||
- "Think about how gaining independence might have changed the lives of the colonists. Consider aspects like freedom, governance, and rights."
|
||||
tokens_for_ai: "Guide the student to think about the impact of independence on the colonists' lives. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think gaining independence changed the lives of the colonists?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the impact of gaining independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the impact of independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the impact of independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Causes of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Taxation Without Representation"
|
||||
content_blocks:
|
||||
- "One of the main causes of the Revolutionary War was the issue of 'taxation without representation.'"
|
||||
- "The British government imposed taxes on the American colonies without giving them representation in Parliament."
|
||||
- "Think about how you would feel if you had to pay taxes but had no say in how the money was spent. How might this lead to frustration and anger?"
|
||||
tokens_for_ai: "Guide the student to think about the feelings of the colonists regarding taxation without representation. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the colonists felt about 'taxation without representation' and why?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the colonists' feelings about 'taxation without representation.'"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on 'taxation without representation.'"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of 'taxation without representation' in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Intolerable Acts"
|
||||
content_blocks:
|
||||
- "The Intolerable Acts were a series of punitive laws passed by the British Parliament in response to the Boston Tea Party."
|
||||
- "These acts further angered the American colonists and contributed to the outbreak of the Revolutionary War."
|
||||
- "Think about how you would feel if you were punished for protesting against something you believed was unfair. How might this lead to a desire for change?"
|
||||
tokens_for_ai: "Guide the student to think about the feelings of the colonists regarding the Intolerable Acts. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the colonists felt about the Intolerable Acts and why?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the colonists' feelings about the Intolerable Acts."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Intolerable Acts."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Intolerable Acts in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Key Events of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Boston Tea Party"
|
||||
content_blocks:
|
||||
- "The Boston Tea Party was a political protest by the Sons of Liberty in Boston, Massachusetts, on December 16, 1773."
|
||||
- "American colonists, frustrated with British taxation, dumped 342 chests of British tea into the harbor."
|
||||
- "Think about why the colonists chose to protest in this way. What message were they trying to send to the British government?"
|
||||
tokens_for_ai: "Guide the student to think about the reasons behind the Boston Tea Party. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the colonists chose to protest by dumping tea into the harbor?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the reasons behind the Boston Tea Party."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Boston Tea Party."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Boston Tea Party in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Battles of Lexington and Concord"
|
||||
content_blocks:
|
||||
- "The Battles of Lexington and Concord were the first military engagements of the American Revolutionary War."
|
||||
- "They were fought on April 19, 1775, in Middlesex County, Province of Massachusetts Bay."
|
||||
- "Think about why these battles were significant. How did they change the relationship between the colonies and Great Britain?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Battles of Lexington and Concord. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Battles of Lexington and Concord were significant?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the significance of the Battles of Lexington and Concord."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battles of Lexington and Concord."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Battles of Lexington and Concord in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Key Figures of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "George Washington"
|
||||
content_blocks:
|
||||
- "George Washington was the commander-in-chief of the Continental Army during the American Revolutionary War."
|
||||
- "He later became the first President of the United States."
|
||||
- "Think about the qualities that made George Washington a good leader. How did his leadership contribute to the success of the American forces?"
|
||||
tokens_for_ai: "Guide the student to think about the qualities of George Washington's leadership. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What qualities do you think made George Washington a good leader and how did his leadership contribute to the success of the American forces?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the qualities that made George Washington a good leader."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on George Washington's leadership qualities."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of George Washington's leadership qualities in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Thomas Jefferson"
|
||||
content_blocks:
|
||||
- "Thomas Jefferson was the principal author of the Declaration of Independence."
|
||||
- "He later became the third President of the United States."
|
||||
- "Think about the impact of the Declaration of Independence. How did Thomas Jefferson's words inspire the colonists and shape the new nation?"
|
||||
tokens_for_ai: "Guide the student to think about the impact of the Declaration of Independence and Thomas Jefferson's role. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think Thomas Jefferson's words in the Declaration of Independence inspired the colonists and shaped the new nation?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the impact of Thomas Jefferson's words in the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Thomas Jefferson's role."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of Thomas Jefferson's role in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Major Battles of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Battle of Bunker Hill"
|
||||
content_blocks:
|
||||
- "The Battle of Bunker Hill was fought on June 17, 1775, during the early stages of the American Revolutionary War."
|
||||
- "Despite being a British victory, the battle demonstrated that the American forces could stand up to the British army."
|
||||
- "Think about the significance of this battle. How might it have affected the morale and determination of the American forces?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Battle of Bunker Hill. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Battle of Bunker Hill was significant for the American forces?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the significance of the Battle of Bunker Hill for the American forces."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battle of Bunker Hill."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Battle of Bunker Hill in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Battle of Saratoga"
|
||||
content_blocks:
|
||||
- "The Battle of Saratoga was a turning point in the American Revolutionary War."
|
||||
- "Fought in 1777, it resulted in a decisive victory for the American forces and convinced France to join the war on the side of the Americans."
|
||||
- "Think about why this battle was a turning point. How did the involvement of France change the course of the war?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Battle of Saratoga. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Battle of Saratoga was a turning point in the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the significance of the Battle of Saratoga."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Battle of Saratoga."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Battle of Saratoga in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "The Declaration of Independence"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Drafting the Declaration"
|
||||
content_blocks:
|
||||
- "The Declaration of Independence was drafted by Thomas Jefferson and adopted by the Continental Congress on July 4, 1776."
|
||||
- "It declared the thirteen American colonies as independent states, free from British rule."
|
||||
- "Think about the significance of declaring independence. How might this document have inspired the colonists and affected their resolve to fight for freedom?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Declaration of Independence. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Declaration of Independence was significant for the colonists?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the significance of the Declaration of Independence for the colonists."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Declaration of Independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Key Principles of the Declaration"
|
||||
content_blocks:
|
||||
- "The Declaration of Independence outlined key principles such as equality, unalienable rights, and the right to alter or abolish government."
|
||||
- "It emphasized that all men are created equal and have the right to life, liberty, and the pursuit of happiness."
|
||||
- "Think about how these principles might have influenced the new nation. How do you think they shaped the values and government of the United States?"
|
||||
tokens_for_ai: "Guide the student to think about the key principles of the Declaration of Independence and their influence. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the key principles of the Declaration of Independence influenced the new nation?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the influence of the key principles of the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the key principles of the Declaration of Independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the key principles of the Declaration of Independence in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "The End of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Siege of Yorktown"
|
||||
content_blocks:
|
||||
- "The Siege of Yorktown was the last major battle of the American Revolutionary War."
|
||||
- "Fought in 1781, it resulted in the surrender of British General Cornwallis and effectively ended the war."
|
||||
- "Think about why this battle was significant. How did the surrender of Cornwallis impact the outcome of the war?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Siege of Yorktown. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Siege of Yorktown was significant in ending the Revolutionary War?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the significance of the Siege of Yorktown in ending the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Siege of Yorktown."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Siege of Yorktown in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "The Treaty of Paris"
|
||||
content_blocks:
|
||||
- "The Treaty of Paris was signed on September 3, 1783, and officially ended the American Revolutionary War."
|
||||
- "The treaty recognized the independence of the United States and established its borders."
|
||||
- "Think about the significance of this treaty. How did it solidify the United States' status as an independent nation?"
|
||||
tokens_for_ai: "Guide the student to think about the significance of the Treaty of Paris. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do you think the Treaty of Paris was significant in solidifying the United States' independence?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the significance of the Treaty of Paris in solidifying the United States' independence."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Treaty of Paris."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the Treaty of Paris in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_8"
|
||||
title: "Legacy of the Revolutionary War"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Impact on the United States"
|
||||
content_blocks:
|
||||
- "The American Revolutionary War had a profound impact on the United States."
|
||||
- "It led to the establishment of a new nation based on principles of liberty, democracy, and self-governance."
|
||||
- "Think about how these principles have shaped the United States. How do you see the influence of the Revolutionary War in the country's values and government today?"
|
||||
tokens_for_ai: "Guide the student to think about the impact of the Revolutionary War on the United States. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the principles established during the Revolutionary War have shaped the United States today?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the impact of the Revolutionary War on the United States today."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the impact of the Revolutionary War."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the impact of the Revolutionary War in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Influence on Other Nations"
|
||||
content_blocks:
|
||||
- "The American Revolutionary War inspired other nations to fight for their independence and adopt democratic principles."
|
||||
- "It had a significant influence on the French Revolution and other independence movements around the world."
|
||||
- "Think about how the success of the American Revolution might have inspired other countries. How do you think it influenced global movements for independence and democracy?"
|
||||
tokens_for_ai: "Guide the student to think about the influence of the American Revolutionary War on other nations. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you think the success of the American Revolution influenced other countries' movements for independence and democracy?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the influence of the American Revolution on other countries."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the influence of the American Revolution."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of the influence of the American Revolution in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_9"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the American Revolutionary War course!"
|
||||
- "You have learned about the causes, key events, major battles, important figures, and the legacy of the Revolutionary War."
|
||||
- "This knowledge will help you understand the foundations of the United States and the principles of liberty and democracy."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
|
@ -1,425 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are a master storyteller. Your task is to create a coherent and engaging story based on the following chat history. The story should seamlessly integrate the user's responses and the AI's feedback, ensuring that the narrative flows naturally. Pay special attention to the user's choices and how they shape the story. Use descriptive language to bring the scenes to life and make the story immersive. The story should have a clear beginning, middle, and end, reflecting the user's journey and the outcomes of their decisions. Here is the chat history.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "The Adventure Begins"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Setting the Scene"
|
||||
content_blocks:
|
||||
- "Welcome to the Story Builder game! 🌟"
|
||||
- "You are about to embark on an exciting adventure. Your choices will shape the story."
|
||||
- "Let's begin by setting the scene. Imagine you are in a dense forest, and you come across a fork in the path."
|
||||
- "To the left, the path leads deeper into the forest, where you hear the sound of a flowing river. To the right, the path leads to a clearing with a mysterious glowing light."
|
||||
tokens_for_ai: "Guide the user to make a choice between the two paths. Provide feedback based on their choice."
|
||||
question: "Which path do you choose? Left (forest) or Right (clearing)? 🤔"
|
||||
buckets:
|
||||
- left_forest
|
||||
- right_clearing
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
left_forest:
|
||||
content_blocks:
|
||||
- "You chose to go left, deeper into the forest. 🌲"
|
||||
- "As you walk, the sound of the river grows louder. You soon find yourself at the edge of a beautiful, sparkling river."
|
||||
- "You notice a small boat tied to a tree. Do you take the boat and explore the river, or do you follow the riverbank on foot?"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
right_clearing:
|
||||
content_blocks:
|
||||
- "You chose to go right, towards the clearing. 🌟"
|
||||
- "As you approach the clearing, the glowing light becomes brighter. You find a magical portal shimmering in the air."
|
||||
- "Do you step through the portal to see where it leads, or do you stay and explore the clearing?"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "The Forest Path"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Encounter at the River"
|
||||
content_blocks:
|
||||
- "You chose to go left, deeper into the forest. 🌲"
|
||||
- "As you walk, the sound of the river grows louder. You soon find yourself at the edge of a beautiful, sparkling river."
|
||||
- "You notice a small boat tied to a tree. Do you take the boat and explore the river, or do you follow the riverbank on foot?"
|
||||
tokens_for_ai: "Guide the user to make a choice between taking the boat or following the riverbank. Provide feedback based on their choice."
|
||||
question: "What do you choose? Take the boat or Follow the riverbank? 🤔"
|
||||
buckets:
|
||||
- take_boat
|
||||
- follow_riverbank
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
take_boat:
|
||||
content_blocks:
|
||||
- "You chose to take the boat and explore the river. 🚣"
|
||||
- "As you paddle down the river, you encounter a group of friendly forest creatures who offer to guide you to a hidden treasure."
|
||||
- "Congratulations! You have discovered a hidden treasure with the help of your new friends. 🎉"
|
||||
next_section_and_step: "section_4:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
follow_riverbank:
|
||||
content_blocks:
|
||||
- "You chose to follow the riverbank on foot. 🌲"
|
||||
- "As you walk along the river, you find a hidden cave entrance. Inside, you discover ancient artifacts and a map to a secret location."
|
||||
- "Congratulations! You have discovered ancient artifacts and a secret map. 🎉"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the fork in the path. 🔄"
|
||||
- "You are now back at the fork. To the left, the path leads deeper into the forest, where you hear the sound of a flowing river. To the right, the path leads to a clearing with a mysterious glowing light."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "The Clearing Path"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Magical Portal"
|
||||
content_blocks:
|
||||
- "You chose to go right, towards the clearing. 🌟"
|
||||
- "As you approach the clearing, the glowing light becomes brighter. You find a magical portal shimmering in the air."
|
||||
- "Do you step through the portal to see where it leads, or do you stay and explore the clearing?"
|
||||
tokens_for_ai: "Guide the user to make a choice between stepping through the portal or exploring the clearing. Provide feedback based on their choice."
|
||||
question: "What do you choose? Step through the portal or Explore the clearing? 🤔"
|
||||
buckets:
|
||||
- step_through_portal
|
||||
- explore_clearing
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
step_through_portal:
|
||||
content_blocks:
|
||||
- "You chose to step through the portal. 🌟"
|
||||
- "You find yourself in a magical realm filled with wonders and mysteries. A wise old wizard offers to teach you powerful spells."
|
||||
- "Congratulations! You have entered a magical realm and begun your training as a wizard. 🎉"
|
||||
next_section_and_step: "section_6:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
explore_clearing:
|
||||
content_blocks:
|
||||
- "You chose to explore the clearing. 🌲"
|
||||
- "You find a hidden garden filled with rare and beautiful plants. A friendly gardener offers to share their knowledge with you."
|
||||
- "Congratulations! You have discovered a hidden garden and gained valuable knowledge. 🎉"
|
||||
next_section_and_step: "section_7:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the fork in the path. 🔄"
|
||||
- "You are now back at the fork. To the left, the path leads deeper into the forest, where you hear the sound of a flowing river. To the right, the path leads to a clearing with a mysterious glowing light."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "The Boat Adventure"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Hidden Treasure"
|
||||
content_blocks:
|
||||
- "You chose to take the boat and explore the river. 🚣"
|
||||
- "As you paddle down the river, you encounter a group of friendly forest creatures who offer to guide you to a hidden treasure."
|
||||
- "You find the hidden treasure chest. Do you open the treasure or leave it?"
|
||||
tokens_for_ai: "Guide the user to make a choice between opening the treasure or leaving it. Provide feedback based on their choice."
|
||||
question: "What do you choose? Open the treasure or Leave it? 🤔"
|
||||
buckets:
|
||||
- open_treasure
|
||||
- leave_treasure
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
open_treasure:
|
||||
content_blocks:
|
||||
- "You chose to open the treasure. 🎉"
|
||||
- "Inside, you find gold coins, precious gems, and a magical artifact that grants you a special power."
|
||||
- "Congratulations! You have discovered a hidden treasure and gained a special power. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
leave_treasure:
|
||||
content_blocks:
|
||||
- "You chose to leave the treasure. 🌲"
|
||||
- "You decide that the adventure itself is the real treasure and continue your journey with a sense of fulfillment."
|
||||
- "Congratulations! You have completed the adventure with a sense of fulfillment. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the river. 🔄"
|
||||
- "You are now back at the river. Do you take the boat and explore the river, or do you follow the riverbank on foot?"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "The Riverbank Adventure"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Hidden Cave"
|
||||
content_blocks:
|
||||
- "You chose to follow the riverbank on foot. 🌲"
|
||||
- "As you walk along the river, you find a hidden cave entrance. Inside, you discover ancient artifacts and a map to a secret location."
|
||||
- "Do you enter the cave or continue walking along the riverbank?"
|
||||
tokens_for_ai: "Guide the user to make a choice between entering the cave or continuing to walk. Provide feedback based on their choice."
|
||||
question: "What do you choose? Enter the cave or Continue walking? 🤔"
|
||||
buckets:
|
||||
- enter_cave
|
||||
- continue_walking
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
enter_cave:
|
||||
content_blocks:
|
||||
- "You chose to enter the cave. 🌲"
|
||||
- "Inside, you find ancient artifacts and a map to a secret location. You feel a sense of discovery and excitement."
|
||||
- "Congratulations! You have discovered ancient artifacts and a secret map. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
continue_walking:
|
||||
content_blocks:
|
||||
- "You chose to continue walking along the riverbank. 🌲"
|
||||
- "As you walk, you find a beautiful waterfall and a hidden path leading to a secret garden."
|
||||
- "Congratulations! You have discovered a hidden garden and gained valuable knowledge. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the river. 🔄"
|
||||
- "You are now back at the river. Do you take the boat and explore the river, or do you follow the riverbank on foot?"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "The Portal Adventure"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Magical Realm"
|
||||
content_blocks:
|
||||
- "You chose to step through the portal. 🌟"
|
||||
- "You find yourself in a magical realm filled with wonders and mysteries. A wise old wizard offers to teach you powerful spells."
|
||||
- "Do you learn spells from the wizard or explore the magical realm on your own?"
|
||||
tokens_for_ai: "Guide the user to make a choice between learning spells or exploring the realm. Provide feedback based on their choice."
|
||||
question: "What do you choose? Learn spells or Explore the realm? 🤔"
|
||||
buckets:
|
||||
- learn_spells
|
||||
- explore_realm
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
learn_spells:
|
||||
content_blocks:
|
||||
- "You chose to learn spells from the wizard. 🌟"
|
||||
- "The wizard teaches you powerful spells that grant you special abilities. You feel a sense of empowerment and wonder."
|
||||
- "Congratulations! You have learned powerful spells and gained special abilities. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
explore_realm:
|
||||
content_blocks:
|
||||
- "You chose to explore the magical realm on your own. 🌟"
|
||||
- "As you explore, you discover hidden treasures and magical creatures. You feel a sense of adventure and excitement."
|
||||
- "Congratulations! You have discovered hidden treasures and magical creatures. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the clearing. 🔄"
|
||||
- "You are now back at the clearing. Do you step through the portal to see where it leads, or do you stay and explore the clearing?"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "The Clearing Adventure"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Hidden Garden"
|
||||
content_blocks:
|
||||
- "You chose to explore the clearing. 🌲"
|
||||
- "You find a hidden garden filled with rare and beautiful plants. A friendly gardener offers to share their knowledge with you."
|
||||
- "Do you talk to the gardener or explore the garden on your own?"
|
||||
tokens_for_ai: "Guide the user to make a choice between talking to the gardener or exploring the garden. Provide feedback based on their choice."
|
||||
question: "What do you choose? Talk to the gardener or Explore the garden? 🤔"
|
||||
buckets:
|
||||
- talk_gardener
|
||||
- explore_garden
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
talk_gardener:
|
||||
content_blocks:
|
||||
- "You chose to talk to the gardener. 🌲"
|
||||
- "The gardener shares their knowledge of rare plants and their magical properties. You feel a sense of wonder and curiosity."
|
||||
- "Congratulations! You have gained valuable knowledge about rare plants and their magical properties. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
explore_garden:
|
||||
content_blocks:
|
||||
- "You chose to explore the garden on your own. 🌲"
|
||||
- "As you explore, you discover hidden paths and secret areas filled with rare plants and magical creatures. You feel a sense of adventure and excitement."
|
||||
- "Congratulations! You have discovered hidden paths and secret areas in the garden. 🎉"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the clearing. 🔄"
|
||||
- "You are now back at the clearing. Do you step through the portal to see where it leads, or do you stay and explore the clearing?"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_8"
|
||||
title: "The Final Choices"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Final Encounter"
|
||||
content_blocks:
|
||||
- "You have reached the final part of your adventure. Your choices have led you to this moment."
|
||||
- "You are presented with a final choice: accept a reward for your journey or decline it and continue your adventure."
|
||||
- "Think about what you have learned and experienced. What will you choose?"
|
||||
tokens_for_ai: "Guide the user to make a final choice between accepting the reward or declining it. Provide feedback based on their choice."
|
||||
question: "What do you choose? Accept the reward or Decline the reward? 🤔"
|
||||
buckets:
|
||||
- accept_reward
|
||||
- decline_reward
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
accept_reward:
|
||||
content_blocks:
|
||||
- "You chose to accept the reward. 🎉"
|
||||
- "You are given a magical artifact that grants you special powers and a sense of accomplishment."
|
||||
- "Congratulations! You have completed your adventure and received a magical reward. 🎉"
|
||||
next_section_and_step: "section_9:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and conclude the story. Use emojis like 👍 and 🌟."
|
||||
decline_reward:
|
||||
content_blocks:
|
||||
- "You chose to decline the reward. 🌲"
|
||||
- "You decide that the journey itself was the true reward and continue your adventure with a sense of fulfillment."
|
||||
- "Congratulations! You have completed your adventure with a sense of fulfillment. 🎉"
|
||||
next_section_and_step: "section_9:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and conclude the story. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the previous step. 🔄"
|
||||
- "You are now back at the previous step. Think about what you have learned and experienced. What will you choose?"
|
||||
next_section_and_step: "section_8:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_9"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Story Builder game! 🎉"
|
||||
- "You have made choices that shaped an exciting adventure."
|
||||
- "We hope you enjoyed the journey and the story you helped create."
|
||||
- "We are proud of your creativity and imagination. Well done! 🌟"
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are a master storyteller. Your task is to create a coherent and engaging story based on the following chat history. The story should seamlessly integrate the user's responses and the AI's feedback, ensuring that the narrative flows naturally. Pay special attention to the user's choices and how they shape the story. Use descriptive language to bring the scenes to life and make the story immersive. The story should have a clear beginning, middle, and end, reflecting the user's journey and the outcomes of their decisions. Here is the chat history.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "The Escape Room Begins"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Waking Up"
|
||||
content_blocks:
|
||||
- "You wake up in a dimly lit room with no memory of how you got there. The room is small and has a single door that is locked."
|
||||
- "You see a rug on the floor, a bookshelf with a book, and a safe on the wall."
|
||||
tokens_for_ai: "Guide the user to make a choice between looking under the rug, examining the book, or trying to open the safe. Provide feedback based on their choice."
|
||||
question: "What do you choose? Look under the rug, Examine the book, or Try to open the safe? 🤔"
|
||||
buckets:
|
||||
- look_under_rug
|
||||
- examine_book
|
||||
- try_open_safe
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
look_under_rug:
|
||||
content_blocks:
|
||||
- "You chose to look under the rug. 🧺"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
key: true
|
||||
examine_book:
|
||||
content_blocks:
|
||||
- "You chose to examine the book. 📖"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
password: true
|
||||
try_open_safe:
|
||||
content_blocks:
|
||||
- "You chose to try to open the safe. 🔒"
|
||||
next_section_and_step: "section_4:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "The Key"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Found the Key"
|
||||
content_blocks:
|
||||
- "You have found a key hidden under the rug. 🔑"
|
||||
tokens_for_ai: "Guide the user to make a choice between taking the key or continuing to explore the room. Provide feedback based on their choice."
|
||||
question: "What do you choose? Take the key or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- take_key
|
||||
- continue_exploring
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
take_key:
|
||||
content_blocks:
|
||||
- "You chose to take the key. 🔑"
|
||||
- "You now have the key."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
key: true
|
||||
continue_exploring:
|
||||
content_blocks:
|
||||
- "You chose to continue exploring the room. 🕵️"
|
||||
- "You see a rug on the floor, a bookshelf with a book, and a safe on the wall."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the previous step. 🔄"
|
||||
- "You are now back at the previous step."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "The Book"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Found the Password"
|
||||
content_blocks:
|
||||
- "The book contains a note with a password: 'ESCAPE123'. 🔐"
|
||||
tokens_for_ai: "Guide the user to make a choice between taking note of the password or continuing to explore the room. Provide feedback based on their choice."
|
||||
question: "What do you choose? Take note of the password or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- take_password
|
||||
- continue_exploring
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
take_password:
|
||||
content_blocks:
|
||||
- "You chose to take note of the password. 🔑"
|
||||
- "You now have the password."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
password: true
|
||||
continue_exploring:
|
||||
content_blocks:
|
||||
- "You chose to continue exploring the room. 🕵️"
|
||||
- "You see a rug on the floor, a bookshelf with a book, and a safe on the wall."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the previous step. 🔄"
|
||||
- "You are now back at the previous step."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "The Safe"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Opening the Safe"
|
||||
content_blocks:
|
||||
- "The safe is locked and requires both a key and a password to open. 🔒"
|
||||
tokens_for_ai: "Guide the user to make a choice between using the key and entering the password to open the safe or continuing to explore the room. Provide feedback based on their choice."
|
||||
question: "What do you choose? Use the key and enter the password or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- use_key_and_password
|
||||
- continue_exploring
|
||||
- go_back
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
use_key_and_password:
|
||||
metadata_conditions:
|
||||
key: true
|
||||
password: true
|
||||
content_blocks:
|
||||
- "You chose to use the key and enter the password to open the safe. 🔑"
|
||||
- "The safe opens, revealing a hidden treasure."
|
||||
- "Congratulations! You have found the hidden treasure. 🎉"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Use emojis like 👍 and 🌟."
|
||||
continue_exploring:
|
||||
content_blocks:
|
||||
- "You chose to continue exploring the room. 🕵️"
|
||||
- "You see a rug on the floor, a bookshelf with a book, and a safe on the wall."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the previous step. 🔄"
|
||||
- "You are now back at the previous step."
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on finding the hidden treasure! 🎉"
|
||||
- "You have successfully completed the escape room."
|
||||
- "We hope you enjoyed the adventure. 🌟"
|
||||
|
||||
|
|
@ -1,361 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are a master storyteller. Your task is to create a coherent and engaging story based on the following chat history. The story should seamlessly integrate the user's responses and the AI's feedback, ensuring that the narrative flows naturally. Pay special attention to the user's choices and how they shape the story. Use descriptive language to bring the scenes to life and make the story immersive. The story should have a clear beginning, middle, and end, reflecting the user's journey and the outcomes of their decisions. Here is the chat history.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "The Escape Room Begins"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Waking Up"
|
||||
content_blocks:
|
||||
- "You wake up in a dimly lit room with no memory of how you got there. The room is small and has a single door that is locked."
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Explore"
|
||||
content_blocks:
|
||||
- "You see a rug on the floor, a bookshelf with a book, and a safe on the wall."
|
||||
- "There is also an exit door, but it seems to be locked."
|
||||
tokens_for_ai: "Guide the user to make a choice between looking under the rug, examining the book, trying to open the safe, or trying to leave the room. Use off_topic sparingly if the response choice doesn't fit any other topic."
|
||||
question: "What do you do? Look under the rug, Examine the book, Try to open the safe, or Try to leave the room? 🤔"
|
||||
buckets:
|
||||
- look_under_rug
|
||||
- examine_book
|
||||
- try_open_safe
|
||||
- try_leave_room
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
look_under_rug:
|
||||
next_section_and_step: "section_2:step_1"
|
||||
examine_book:
|
||||
next_section_and_step: "section_3:step_1"
|
||||
try_open_safe:
|
||||
next_section_and_step: "section_4:step_1"
|
||||
try_leave_room:
|
||||
metadata_conditions:
|
||||
exit_key: true
|
||||
content_blocks:
|
||||
- "You chose to try to leave the room. 🚪"
|
||||
- "The exit door opens, revealing a way out."
|
||||
- "Congratulations! You have found the way out and successfully completed the escape room. 🎉"
|
||||
next_section_and_step: "section_6:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The user has exited with the exit_key! The game is over, Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "The Key"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Found the Key"
|
||||
content_blocks:
|
||||
- "You find a key hidden under the rug. 🔑"
|
||||
tokens_for_ai: "Guide the user to make a choice between taking the key or continuing to explore the room. Be flexible to classify actions that lead to finding hidden items. Use off_topic sparingly if the response choice doesn't fit any other topic. Provide feedback based on their choice."
|
||||
question: "What do you choose? Take the key or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- take_key
|
||||
- continue_exploring
|
||||
- find_coin
|
||||
- go_back
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
take_key:
|
||||
content_blocks:
|
||||
- "You chose to take the key. 🔑"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
metadata_add:
|
||||
key: true
|
||||
continue_exploring:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
find_coin:
|
||||
content_blocks:
|
||||
- "You chose to take a closer look under the rug. 🧺"
|
||||
- "You find a small, mysterious coin with strange engravings."
|
||||
- "You now have the coin!"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The player found a hidden coin. Congratulate them by name with your feedback. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
coin: true
|
||||
go_back:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the story. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "The Book"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Found the Password"
|
||||
content_blocks:
|
||||
- "The book contains a note with a password: 'ESCAPE123'. 🔐"
|
||||
tokens_for_ai: "Guide the user to make a choice between taking note of the password or continuing to explore the room. Be flexible to classify actions that lead to finding hidden items. Use off_topic sparingly if the response choice doesn't fit any other topic. Provide feedback based on their choice."
|
||||
question: "What do you choose? Take note of the password or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- take_password
|
||||
- continue_exploring
|
||||
- find_paper
|
||||
- go_back
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
take_password:
|
||||
content_blocks:
|
||||
- "You chose to take note of the password. 🔑"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
metadata_add:
|
||||
password: true
|
||||
continue_exploring:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
find_paper:
|
||||
content_blocks:
|
||||
- "You chose to take a closer look at the book. 📖"
|
||||
- "You find a small, folded piece of paper with a cryptic message."
|
||||
- "You take the paper!"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The player found a hidden paper with a cryptic message. Congratulate them by name with your feedback. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
paper: true
|
||||
go_back:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "The Safe"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Opening the Safe"
|
||||
content_blocks:
|
||||
- "The safe is locked and requires both a key and a password to open. 🔒"
|
||||
tokens_for_ai: "Guide the user to make a choice between using the key and entering the password to open the safe or continuing to explore the room. Be flexible to classify actions that lead to finding hidden items. Use off_topic sparingly if the response choice doesn't fit any other topic. Provide feedback based on their choice."
|
||||
question: "What do you do? Use the key and enter the password or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- use_key_and_password
|
||||
- continue_exploring
|
||||
- go_back
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
use_key_and_password:
|
||||
metadata_conditions:
|
||||
key: true
|
||||
password: true
|
||||
content_blocks:
|
||||
- "You chose to use the key and enter the password to open the safe. 🔑"
|
||||
- "The safe opens, revealing a hidden treasure and the exit key. 🎉"
|
||||
- "There is also a slot for a coin, but that is likely not important..."
|
||||
next_section_and_step: "section_4:step_2"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
second_safe: true
|
||||
exit_key: true
|
||||
continue_exploring:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
go_back:
|
||||
next_section_and_step: "section_3:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Safe is Open"
|
||||
content_blocks:
|
||||
- "The safe is now open, revealing treasure and an exit key. 🎉"
|
||||
- "There is a coin slot in the safe that looks intriguing. 🪙"
|
||||
tokens_for_ai: "Guide the user to make a choice: If they mention 'use coin', 'coin slot', or 'insert coin' categorize as 'use_coin'. If they want to continue exploring or leave, categorize accordingly."
|
||||
question: "What do you do? Use the coin in the slot, Try to leave the room, or Continue exploring? 🤔"
|
||||
buckets:
|
||||
- use_coin
|
||||
- try_leave_room
|
||||
- continue_exploring
|
||||
- go_back
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
use_coin:
|
||||
metadata_conditions:
|
||||
coin: true
|
||||
second_safe: true
|
||||
metadata_remove:
|
||||
- coin
|
||||
next_section_and_step: "section_5:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
try_leave_room:
|
||||
metadata_conditions:
|
||||
exit_key: true
|
||||
content_blocks:
|
||||
- "You chose to try to leave the room. 🚪"
|
||||
- "The exit door opens, revealing a way out."
|
||||
- "Congratulations! You have found the way out and successfully completed the escape room. 🎉"
|
||||
next_section_and_step: "section_6:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The user has exited with the exit_key! The game is over, Use emojis like 👍 and 🌟."
|
||||
continue_exploring:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
go_back:
|
||||
next_section_and_step: "section_4:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "The Secret Compartment"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Hidden Compartment"
|
||||
content_blocks:
|
||||
- "The compartment opens, revealing a second, smaller safe. 🪙"
|
||||
- "This safe requires a combination to open."
|
||||
tokens_for_ai: "Guide the user to make a choice between solving the combination to open the second safe or leaving it alone. Be flexible to classify actions that lead to finding hidden items. Use off_topic sparingly if the response choice doesn't fit any other topic. Provide feedback based on their choice."
|
||||
question: "Do you try to solve the combination or leave it alone? 🤔"
|
||||
buckets:
|
||||
- solve_combination
|
||||
- leave_it_alone
|
||||
- go_back
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
solve_combination:
|
||||
metadata_conditions:
|
||||
paper: true
|
||||
content_blocks:
|
||||
- "You chose to solve the combination. 🧩"
|
||||
- "After some thought, you decipher the cryptic message and enter the combination."
|
||||
- "The second safe opens, revealing a map to a hidden location outside the room."
|
||||
- "Congratulations! You have found the ultimate secret and a new adventure awaits. 🎉"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Congratulate the player by name for finding ultimate secret. Use emojis like 👍 and 🌟."
|
||||
leave_it_alone:
|
||||
next_section_and_step: "section_1:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the final encounter. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
go_back:
|
||||
next_section_and_step: "section_4:step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to make the next choice. Be flexible to classify actions that lead to finding hidden items. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "Prize Room"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Choose Your Prize"
|
||||
content_blocks:
|
||||
- "You have reached the prize room! 🎁"
|
||||
- "There are 10 different items in the room. One is your prize."
|
||||
tokens_for_ai: "Randomly select one of the following prize_ items as the user's prize."
|
||||
question: "Guess your prize? 🤔"
|
||||
buckets:
|
||||
- prize_1
|
||||
- prize_2
|
||||
- prize_3
|
||||
- prize_4
|
||||
- prize_5
|
||||
- prize_6
|
||||
- prize_7
|
||||
- prize_8
|
||||
- prize_9
|
||||
- prize_10
|
||||
transitions:
|
||||
prize_1:
|
||||
content_blocks:
|
||||
- "You won Prize 1: A golden keychain. 🗝️"
|
||||
metadata_add:
|
||||
prize: golden_keychain
|
||||
prize_2:
|
||||
content_blocks:
|
||||
- "You won Prize 2: A mysterious amulet. 🧿"
|
||||
metadata_add:
|
||||
prize: mysterious_amulet
|
||||
prize_3:
|
||||
content_blocks:
|
||||
- "You won Prize 3: A rare gemstone. 💎"
|
||||
metadata_add:
|
||||
prize: rare_gemstone
|
||||
prize_4:
|
||||
content_blocks:
|
||||
- "You won Prize 4: An ancient scroll. 📜"
|
||||
metadata_add:
|
||||
prize: ancient_scroll
|
||||
prize_5:
|
||||
content_blocks:
|
||||
- "You won Prize 5: A magical wand. 🪄"
|
||||
metadata_add:
|
||||
prize: magical_wand
|
||||
prize_6:
|
||||
content_blocks:
|
||||
- "You won Prize 6: A treasure map. 🗺️"
|
||||
metadata_add:
|
||||
prize: treasure_map
|
||||
prize_7:
|
||||
content_blocks:
|
||||
- "You won Prize 7: A silver coin. 🪙"
|
||||
metadata_add:
|
||||
prize: silver_coin
|
||||
prize_8:
|
||||
content_blocks:
|
||||
- "You won Prize 8: A mystical ring. 💍"
|
||||
metadata_add:
|
||||
prize: mystical_ring
|
||||
prize_9:
|
||||
content_blocks:
|
||||
- "You won Prize 9: A rare book. 📚"
|
||||
metadata_add:
|
||||
prize: rare_book
|
||||
prize_10:
|
||||
content_blocks:
|
||||
- "You won Prize 10: A magical potion. 🧪"
|
||||
metadata_add:
|
||||
prize: magical_potion
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on finding the hidden treasure! 🎉"
|
||||
- "You have successfully completed the escape room."
|
||||
- "We hope you enjoyed the adventure. 🌟"
|
||||
|
|
@ -1,286 +0,0 @@
|
|||
default_max_attempts_per_step: 8
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
Review the conversation and highlight the statements or questions that the user asked and anything they learned. A summary.
|
||||
|
||||
sections:
|
||||
- section_id: "introduction"
|
||||
title: "Introduction"
|
||||
steps:
|
||||
- step_id: "intro_step_1"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "Welcome to the Learning Activity! 📚"
|
||||
- "In this activity, you will go through three lessons."
|
||||
- "After completing all lessons, you will be able to exit."
|
||||
|
||||
- step_id: "intro_step_2"
|
||||
title: "Choose a Lesson"
|
||||
content_blocks:
|
||||
- "You can choose to review any of the lessons or exit if you have completed all lessons."
|
||||
- "Lesson 1: Topic 1 - Introduction to fundamental principles."
|
||||
- "Lesson 2: Topic 2 - Understanding data structures."
|
||||
- "Lesson 3: Topic 3 - Learning about algorithms."
|
||||
question: "Which lesson would you like to review or would you like to exit? 🤔"
|
||||
tokens_for_ai: "Guide the user to choose a lesson or exit. Provide positive reinforcement. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- lesson_1
|
||||
- lesson_2
|
||||
- lesson_3
|
||||
- exit
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
lesson_1:
|
||||
next_section_and_step: "lesson_1:lesson1_step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Guide the user to Lesson 1 about fundamental principles. Use emojis like 🔄 and 🌟."
|
||||
lesson_2:
|
||||
next_section_and_step: "lesson_2:lesson2_step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Guide the user to Lesson 2 about data structures. Use emojis like 🔄 and 🌟."
|
||||
lesson_3:
|
||||
next_section_and_step: "lesson_3:lesson3_step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Guide the user to Lesson 3 about algorithms. Use emojis like 🔄 and 🌟."
|
||||
exit:
|
||||
metadata_conditions:
|
||||
lesson_1_completed: true
|
||||
lesson_2_completed: true
|
||||
lesson_3_completed: true
|
||||
next_section_and_step: "exit:exit_step_1"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the exit. Use emojis like 👍 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the activity in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "lesson_1"
|
||||
title: "Lesson 1: Topic 1"
|
||||
steps:
|
||||
- step_id: "lesson1_step_1"
|
||||
title: "Introduction to Topic 1"
|
||||
content_blocks:
|
||||
- "Welcome to Lesson 1! 📝"
|
||||
- "In this lesson, you will learn about Topic 1."
|
||||
- "Topic 1 is important because it lays the foundation for understanding more complex concepts."
|
||||
|
||||
- step_id: "lesson1_step_2"
|
||||
title: "Basics of Topic 1"
|
||||
content_blocks:
|
||||
- "Let's start with the basics of Topic 1. 📝"
|
||||
- "Topic 1 involves understanding the fundamental principles that will be built upon in later lessons."
|
||||
- "For example, if Topic 1 is about programming, you might learn about variables, data types, and control structures."
|
||||
question: "Do you understand the basics of Topic 1? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the basics of Topic 1, which includes variables, data types, and control structures. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "lesson_1:lesson1_step_3"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the next step. Use emojis like 👍 and 🌟."
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the basics of Topic 1 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the basics of Topic 1. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- step_id: "lesson1_step_3"
|
||||
title: "Advanced Concepts in Topic 1"
|
||||
content_blocks:
|
||||
- "Now that you understand the basics, let's move on to some advanced concepts in Topic 1. 📝"
|
||||
- "These concepts will help you gain a deeper understanding and apply what you've learned in more complex scenarios."
|
||||
- "For example, if Topic 1 is about programming, you might learn about functions, classes, and modules."
|
||||
question: "Do you understand the advanced concepts of Topic 1? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the advanced concepts of Topic 1, which includes functions, classes, and modules. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "introduction:intro_step_2"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user back to the introduction. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
lesson_1_completed: true
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the advanced concepts of Topic 1 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the advanced concepts of Topic 1. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "lesson_2"
|
||||
title: "Lesson 2: Topic 2"
|
||||
steps:
|
||||
- step_id: "lesson2_step_1"
|
||||
title: "Introduction to Topic 2"
|
||||
content_blocks:
|
||||
- "Welcome to Lesson 2! 📝"
|
||||
- "In this lesson, you will learn about Topic 2."
|
||||
- "Topic 2 builds on what you learned in Topic 1 and introduces new concepts."
|
||||
|
||||
- step_id: "lesson2_step_2"
|
||||
title: "Basics of Topic 2"
|
||||
content_blocks:
|
||||
- "Let's start with the basics of Topic 2. 📝"
|
||||
- "Topic 2 involves understanding the fundamental principles that will be built upon in later lessons."
|
||||
- "For example, if Topic 2 is about data structures, you might learn about arrays, linked lists, and stacks."
|
||||
question: "Do you understand the basics of Topic 2? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the basics of Topic 2, which includes arrays, linked lists, and stacks. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "lesson_2:lesson2_step_3"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the next step. Use emojis like 👍 and 🌟."
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the basics of Topic 2 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the basics of Topic 2. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- step_id: "lesson2_step_3"
|
||||
title: "Advanced Concepts in Topic 2"
|
||||
content_blocks:
|
||||
- "Now that you understand the basics, let's move on to some advanced concepts in Topic 2. 📝"
|
||||
- "These concepts will help you gain a deeper understanding and apply what you've learned in more complex scenarios."
|
||||
- "For example, if Topic 2 is about data structures, you might learn about trees, graphs, and hash tables."
|
||||
question: "Do you understand the advanced concepts of Topic 2? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the advanced concepts of Topic 2, which includes trees, graphs, and hash tables. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "introduction:intro_step_2"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user back to the introduction. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
lesson_2_completed: true
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the advanced concepts of Topic 2 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the advanced concepts of Topic 2. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "lesson_3"
|
||||
title: "Lesson 3: Topic 3"
|
||||
steps:
|
||||
- step_id: "lesson3_step_1"
|
||||
title: "Introduction to Topic 3"
|
||||
content_blocks:
|
||||
- "Welcome to Lesson 3! 📝"
|
||||
- "In this lesson, you will learn about Topic 3."
|
||||
- "Topic 3 builds on what you learned in Topics 1 and 2 and introduces new concepts."
|
||||
|
||||
- step_id: "lesson3_step_2"
|
||||
title: "Basics of Topic 3"
|
||||
content_blocks:
|
||||
- "Let's start with the basics of Topic 3. 📝"
|
||||
- "Topic 3 involves understanding the fundamental principles that will be built upon in later lessons."
|
||||
- "For example, if Topic 3 is about algorithms, you might learn about sorting, searching, and recursion."
|
||||
question: "Do you understand the basics of Topic 3? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the basics of Topic 3, which includes sorting, searching, and recursion. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "lesson_3:lesson3_step_3"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user to the next step. Use emojis like 👍 and 🌟."
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the basics of Topic 3 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the basics of Topic 3. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- step_id: "lesson3_step_3"
|
||||
title: "Advanced Concepts in Topic 3"
|
||||
content_blocks:
|
||||
- "Now that you understand the basics, let's move on to some advanced concepts in Topic 3. 📝"
|
||||
- "These concepts will help you gain a deeper understanding and apply what you've learned in more complex scenarios."
|
||||
- "For example, if Topic 3 is about algorithms, you might learn about dynamic programming, graph algorithms, and optimization techniques."
|
||||
question: "Do you understand the advanced concepts of Topic 3? 🤔"
|
||||
tokens_for_ai: "Guide the user to confirm their understanding of the advanced concepts of Topic 3, which includes dynamic programming, graph algorithms, and optimization techniques. Provide positive reinforcement. If the user asks clarifying questions, provide detailed explanations and examples. Use emojis like 👍 and 🌟."
|
||||
buckets:
|
||||
- understand
|
||||
- not_understand
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
understand:
|
||||
next_section_and_step: "introduction:intro_step_2"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and guide the user back to the introduction. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
lesson_3_completed: true
|
||||
not_understand:
|
||||
content_blocks:
|
||||
- "Let's review the advanced concepts of Topic 3 again. 📝"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide supportive feedback and review the advanced concepts of Topic 3. Use emojis like 📝 and 🌟."
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the lesson in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions with detailed explanations and examples. Provide comprehensive and helpful feedback. Use emojis like ❓ and 💬."
|
||||
|
||||
- section_id: "exit"
|
||||
title: "Exit"
|
||||
steps:
|
||||
- step_id: "exit_step_1"
|
||||
title: "Congratulations!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing all the lessons! 🎉"
|
||||
- "You have successfully completed the activity."
|
||||
- "We hope you enjoyed the learning experience. 🌟"
|
||||
- "Thank you for participating! Goodbye! 👋"
|
||||
|
|
@ -1,332 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are a master storyteller. Your task is to create a coherent and engaging story based on the following chat history. The story should seamlessly integrate the user's responses and the AI's feedback, ensuring that the narrative flows naturally. Pay special attention to the user's choices and how they shape the story. Use descriptive language to bring the scenes to life and make the story immersive. The story should have a clear beginning, middle, and end, reflecting the user's journey and the outcomes of their decisions. Here is the chat history.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "The Prize Room"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Receive Your Prize"
|
||||
content_blocks:
|
||||
- "You have entered the prize room! 🎁"
|
||||
- "A prize is randomly selected for you from the room."
|
||||
- "You can also go to the temple pit from here."
|
||||
tokens_for_ai: "DO NOT select go_back unless the users says 'go back' in their message."
|
||||
question: "You have received a prize! Guess what it could be? 🤔"
|
||||
buckets:
|
||||
- random_prize_guess
|
||||
- go_to_temple_pit
|
||||
- go_back
|
||||
transitions:
|
||||
random_prize_guess:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "cheer for the player, they got a new item. list them all from metadata. now make a joke about their guess!"
|
||||
|
||||
content_blocks:
|
||||
- "You received a random prize! 🎲"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
metadata_random:
|
||||
golden_keychain: true
|
||||
mysterious_amulet: true
|
||||
rare_gemstone: true
|
||||
ancient_scroll: true
|
||||
magical_wand: true
|
||||
treasure_map: true
|
||||
silver_coin: true
|
||||
mystical_ring: true
|
||||
rare_book: true
|
||||
magical_potion: true
|
||||
shadow_charm: true
|
||||
flame_charm: true
|
||||
|
||||
go_to_temple_pit:
|
||||
content_blocks:
|
||||
- "You chose to go to the temple pit room. 🏛"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the temple pit room. 🏛"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "The Temple Pit"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Offer to the God"
|
||||
content_blocks:
|
||||
- "You have entered the temple pit. 🏛"
|
||||
- "You can offer an item to the god to receive a new item."
|
||||
tokens_for_ai: "Guide the user to make a choice between offering different items."
|
||||
question: "Which item do you offer to the god? 🤔"
|
||||
buckets:
|
||||
- offer_golden_keychain
|
||||
- offer_mysterious_amulet
|
||||
- offer_rare_gemstone
|
||||
- offer_ancient_scroll
|
||||
- offer_magical_wand
|
||||
- offer_treasure_map
|
||||
- offer_silver_coin
|
||||
- offer_mystical_ring
|
||||
- offer_rare_book
|
||||
- offer_magical_potion
|
||||
- offer_shadow_charm
|
||||
- offer_flame_charm
|
||||
- go_back
|
||||
- off_topic
|
||||
transitions:
|
||||
offer_golden_keychain:
|
||||
metadata_conditions:
|
||||
golden_keychain: true
|
||||
content_blocks:
|
||||
- "You offered the golden keychain to the god. 🗝"
|
||||
- "The god grants you a mystical amulet. 🧿"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
mystical_amulet: true
|
||||
metadata_remove:
|
||||
- golden_keychain
|
||||
offer_mysterious_amulet:
|
||||
metadata_conditions:
|
||||
mysterious_amulet: true
|
||||
content_blocks:
|
||||
- "You offered the mysterious amulet to the god. 🧿"
|
||||
- "The god grants you a rare gemstone. 💎"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
rare_gemstone: true
|
||||
metadata_remove:
|
||||
- mysterious_amulet
|
||||
offer_rare_gemstone:
|
||||
metadata_conditions:
|
||||
rare_gemstone: true
|
||||
content_blocks:
|
||||
- "You offered the rare gemstone to the god. 💎"
|
||||
- "The god grants you an ancient scroll. 📜"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
ancient_scroll: true
|
||||
metadata_remove:
|
||||
- rare_gemstone
|
||||
offer_ancient_scroll:
|
||||
metadata_conditions:
|
||||
ancient_scroll: true
|
||||
content_blocks:
|
||||
- "You offered the ancient scroll to the god. 📜"
|
||||
- "The god grants you a magical wand. 🪄"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
magical_wand: true
|
||||
metadata_remove:
|
||||
- ancient_scroll
|
||||
offer_magical_wand:
|
||||
metadata_conditions:
|
||||
magical_wand: true
|
||||
content_blocks:
|
||||
- "You offered the magical wand to the god. 🪄"
|
||||
- "The god grants you a treasure map. 🗺"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
treasure_map: true
|
||||
metadata_remove:
|
||||
- magical_wand
|
||||
offer_treasure_map:
|
||||
metadata_conditions:
|
||||
treasure_map: true
|
||||
content_blocks:
|
||||
- "You offered the treasure map to the god. 🗺"
|
||||
- "The god grants you a silver coin. 🪙"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
silver_coin: true
|
||||
metadata_remove:
|
||||
- treasure_map
|
||||
offer_silver_coin:
|
||||
metadata_conditions:
|
||||
silver_coin: true
|
||||
content_blocks:
|
||||
- "You offered the silver coin to the god. 🪙"
|
||||
- "The god grants you a mystical ring. 💍"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
mystical_ring: true
|
||||
metadata_remove:
|
||||
- silver_coin
|
||||
offer_mystical_ring:
|
||||
metadata_conditions:
|
||||
mystical_ring: true
|
||||
content_blocks:
|
||||
- "You offered the mystical ring to the god. 💍"
|
||||
- "The god grants you a rare book. 📚"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
rare_book: true
|
||||
metadata_remove:
|
||||
- mystical_ring
|
||||
offer_rare_book:
|
||||
metadata_conditions:
|
||||
rare_book: true
|
||||
content_blocks:
|
||||
- "You offered the rare book to the god. 📚"
|
||||
- "The god grants you a magical potion. 🧪"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
magical_potion: true
|
||||
metadata_remove:
|
||||
- rare_book
|
||||
offer_magical_potion:
|
||||
metadata_conditions:
|
||||
magical_potion: true
|
||||
content_blocks:
|
||||
- "You offered the magical potion to the god. 🧪"
|
||||
- "The god grants you a golden keychain. 🗝"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
metadata_add:
|
||||
golden_keychain: true
|
||||
metadata_remove:
|
||||
- magical_potion
|
||||
offer_shadow_charm:
|
||||
metadata_conditions:
|
||||
shadow_charm: true
|
||||
metadata_remove:
|
||||
- shadow_charm
|
||||
content_blocks:
|
||||
- "You offered the Shadow Charm to the god. 🖤"
|
||||
- "The god summons the Shadow Beast! Prepare for battle!"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
offer_flame_charm:
|
||||
metadata_conditions:
|
||||
flame_charm: true
|
||||
metadata_remove:
|
||||
- flame_charm
|
||||
content_blocks:
|
||||
- "You offered the Flame Charm to the god. 🔥"
|
||||
- "The god summons the Fire Drake! Prepare for battle!"
|
||||
next_section_and_step: "section_4:step_1"
|
||||
go_back:
|
||||
content_blocks:
|
||||
- "You chose to go back to the prize room. 🎁"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
off_topic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. DO NOT ask any questions. Use emojis like 🔄 and 🧭."
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "The Dark Cavern"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Battle the Shadow Beast"
|
||||
content_blocks:
|
||||
- "You have entered the Dark Cavern. The air is thick with darkness, and a menacing growl echoes around you."
|
||||
- "A Shadow Beast emerges from the shadows, ready to attack!"
|
||||
tokens_for_ai: "Guide the user to choose their action based on their items."
|
||||
question: "Do you fight the Shadow Beast? (You need the Magical Wand or Mystical Ring to win!)"
|
||||
buckets:
|
||||
- fight_with_wand
|
||||
- fight_with_ring
|
||||
- flee
|
||||
transitions:
|
||||
fight_with_wand:
|
||||
metadata_conditions:
|
||||
magical_wand: true
|
||||
content_blocks:
|
||||
- "You wield the Magical Wand and unleash a powerful spell!"
|
||||
- "The Shadow Beast is defeated! You find a Shadow Crystal. 💎"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
metadata_add:
|
||||
shadow_crystal: true
|
||||
fight_with_ring:
|
||||
metadata_conditions:
|
||||
mystical_ring: true
|
||||
content_blocks:
|
||||
- "You use the Mystical Ring to channel your inner light!"
|
||||
- "The Shadow Beast is defeated! You find a Shadow Crystal. 💎"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
metadata_add:
|
||||
shadow_crystal: true
|
||||
flee:
|
||||
content_blocks:
|
||||
- "You attempt to flee, but the Shadow Beast catches you. You have met your end. 💀"
|
||||
next_section_and_step: "death_ending:step_1"
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "The Fiery Lair"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Battle the Fire Drake"
|
||||
content_blocks:
|
||||
- "You have entered the Fiery Lair. The heat is intense, and flames flicker around you."
|
||||
- "A Fire Drake roars, ready to defend its territory!"
|
||||
tokens_for_ai: "Guide the user to choose their action based on their items."
|
||||
question: "Do you fight the Fire Drake? (You need the Treasure Map or Ancient Scroll to win!)"
|
||||
buckets:
|
||||
- fight_with_map
|
||||
- fight_with_scroll
|
||||
- flee
|
||||
transitions:
|
||||
fight_with_map:
|
||||
metadata_conditions:
|
||||
treasure_map: true
|
||||
content_blocks:
|
||||
- "You use the Treasure Map to find the Drake's weak spot!"
|
||||
- "The Fire Drake is defeated! You find a Flame Pendant. 🔥"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
metadata_add:
|
||||
flame_pendant: true
|
||||
fight_with_scroll:
|
||||
metadata_conditions:
|
||||
ancient_scroll: true
|
||||
content_blocks:
|
||||
- "You read the Ancient Scroll and summon a powerful fire shield!"
|
||||
- "The Fire Drake is defeated! You find a Flame Pendant. 🔥"
|
||||
next_section_and_step: "section_5:step_1"
|
||||
metadata_add:
|
||||
flame_pendant: true
|
||||
flee:
|
||||
content_blocks:
|
||||
- "You attempt to flee, but the Fire Drake incinerates you. You have met your end. 💀"
|
||||
next_section_and_step: "death_ending_fire:step_1"
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "The Final Path"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "The Final Path"
|
||||
content_blocks:
|
||||
- "You have defeated the monster and continue on your journey."
|
||||
- "You see a path leading to the final destination."
|
||||
tokens_for_ai: "Guide the user to the final victory."
|
||||
question: "Do you continue on the path to victory? 🤔"
|
||||
buckets:
|
||||
- continue_to_victory
|
||||
transitions:
|
||||
continue_to_victory:
|
||||
content_blocks:
|
||||
- "You walk down the path and reach the final destination. You are victorious! 🏆"
|
||||
next_section_and_step: "victory:step_1"
|
||||
|
||||
- section_id: "death_ending"
|
||||
title: "The Abyss of Shadows"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Death Ending"
|
||||
content_blocks:
|
||||
- "Game Over."
|
||||
|
||||
- section_id: "death_ending_fire"
|
||||
title: "The Ashen Wastes"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Death Ending"
|
||||
content_blocks:
|
||||
- "Game Over."
|
||||
|
||||
- section_id: "victory"
|
||||
title: "Victory"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Victory"
|
||||
content_blocks:
|
||||
- "Thank you for playing!"
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Rock-Paper-Scissors with History"
|
||||
steps:
|
||||
|
||||
- step_id: "step_0"
|
||||
title: "Challenge a Historical Figure"
|
||||
content_blocks:
|
||||
- "Welcome to the Rock-Paper-Scissors challenge! 🎮"
|
||||
- "You will be playing against a random historical figure."
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Shoot against a Historical Figure"
|
||||
tokens_for_ai: |
|
||||
Careful to check if user is trying to 'set_language' and do that first. otherwise figure out if they are picking the bucket rock, paper, or scissors.
|
||||
feedback_tokens_for_ai: |
|
||||
Speaking in first person as a historical figure, firstly announce your move based on the metadata and then on a new line,
|
||||
Determine who wins the game, use 'user_choice' against the given `ai_` value.
|
||||
|
||||
The rules are simple:
|
||||
|
||||
* rock always beats scissors
|
||||
* paper always beats rock
|
||||
* scissors always beats paper
|
||||
|
||||
Finally continue to provide a witty fact as the figure. Don't ever mention AI.
|
||||
The figure should also comment on the 'attempts' number and how many times played!
|
||||
if you feel like it, jeer at the player about an early 'exit' & suggest they quit.
|
||||
|
||||
question: "What's your choice? Rock, paper, or scissors? 🤔"
|
||||
buckets:
|
||||
- rock
|
||||
- paper
|
||||
- scissors
|
||||
- set_language
|
||||
- exit
|
||||
transitions:
|
||||
rock:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Declare your move and then determine who wins the game and provide a witty fact from the historical figure's perspective."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
metadata_tmp_add:
|
||||
user_choice: "rock"
|
||||
metadata_tmp_random:
|
||||
ai_rock: true
|
||||
ai_paper: true
|
||||
ai_scissors: true
|
||||
next_section_and_step: "section_1:step_1"
|
||||
paper:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Declare your move and then determine who wins the game and provide a witty fact from the historical figure's perspective."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
metadata_tmp_add:
|
||||
user_choice: "paper"
|
||||
metadata_tmp_random:
|
||||
ai_rock: true
|
||||
ai_paper: true
|
||||
ai_scissors: true
|
||||
next_section_and_step: "section_1:step_1"
|
||||
scissors:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Declare your move and determine who wins the game and provide a witty fact from the historical figure's perspective."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
metadata_tmp_add:
|
||||
user_choice: "scissors"
|
||||
metadata_tmp_random:
|
||||
ai_rock: true
|
||||
ai_paper: true
|
||||
ai_scissors: true
|
||||
next_section_and_step: "section_1:step_1"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
exit:
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Goodbye"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Exit"
|
||||
content_blocks:
|
||||
- "Thank you for playing! We hope you enjoyed the game. Have a great day! 🌟"
|
||||
|
|
@ -1,292 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Python"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Python?"
|
||||
content_blocks:
|
||||
- "Welcome to the Python programming course."
|
||||
- "Python is a high-level, interpreted programming language known for its readability and versatility."
|
||||
tokens_for_ai: "Explain what Python is and its key features in a friendly and engaging manner."
|
||||
question: "What do you know about Python?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of Python."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of Python. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Python."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Python in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Installing Python"
|
||||
content_blocks:
|
||||
- "To start coding in Python, you need to install it on your computer."
|
||||
- "You can download Python from the official website: https://www.python.org/downloads/"
|
||||
tokens_for_ai: "Explain how to install Python on different operating systems in a friendly and engaging manner."
|
||||
question: "Have you installed Python on your computer?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You are ready to start coding in Python."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have some issues with the installation. Let's go over the steps again."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide detailed installation steps to help the user in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on installing Python."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of installing Python in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Basic Python Syntax"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Writing Your First Python Program"
|
||||
content_blocks:
|
||||
- "Let's write your first Python program."
|
||||
- "Open a text editor and type the following code:\n```python\nprint('Hello, World!')\n```"
|
||||
- "Save the file with a `.py` extension and run it using the Python interpreter."
|
||||
tokens_for_ai: "Explain how to write and run a simple Python program in a friendly and engaging manner."
|
||||
question: "Were you able to run the 'Hello, World!' program?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You've written and run your first Python program."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you had some issues. Let's go over the steps again."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide detailed steps to help the user run the program successfully in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on writing and running the Python program."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of writing and running the Python program in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Variables and Data Types"
|
||||
content_blocks:
|
||||
- "In Python, you can store data in variables."
|
||||
- "Python supports various data types such as integers, floats, strings, and booleans."
|
||||
- "Here's an example:\n```python\nx = 5\npi = 3.14\nname = 'Alice'\nis_student = True\n```"
|
||||
tokens_for_ai: "Explain variables and data types in Python with examples in a friendly and engaging manner."
|
||||
question: "Can you create a variable and assign a value to it?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You have successfully created a variable."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples and explanations to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on variables and data types."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of variables and data types in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Control Flow"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "If Statements"
|
||||
content_blocks:
|
||||
- "If statements allow you to execute code based on certain conditions."
|
||||
- "Here's an example:\n```python\nx = 10\nif x > 5:\n print('x is greater than 5')\nelse:\n print('x is 5 or less')\n```"
|
||||
tokens_for_ai: "Explain if statements in Python with examples in a friendly and engaging manner."
|
||||
question: "Can you write an if statement to check if a number is positive?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You've written a correct if statement."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples and explanations to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on if statements."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of if statements in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "For Loops"
|
||||
content_blocks:
|
||||
- "For loops allow you to iterate over a sequence of elements."
|
||||
- "Here's an example:\n```python\nfor i in range(5):\n print(i)\n```"
|
||||
tokens_for_ai: "Explain for loops in Python with examples in a friendly and engaging manner."
|
||||
question: "Can you write a for loop to print the numbers from 1 to 10?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You've written a correct for loop."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples and explanations to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on for loops."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of for loops in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Functions"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Defining Functions"
|
||||
content_blocks:
|
||||
- "Functions allow you to encapsulate code into reusable blocks."
|
||||
- "Here's an example:\n```python\ndef greet(name):\n print(f'Hello, {name}!')\n\ngreet('Alice')\n```"
|
||||
tokens_for_ai: "Explain how to define and use functions in Python with examples in a friendly and engaging manner."
|
||||
question: "Can you define a function that takes two numbers and returns their sum?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You've defined a correct function."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples and explanations to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on defining functions."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of defining functions in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Calling Functions"
|
||||
content_blocks:
|
||||
- "Once you've defined a function, you can call it to execute the code inside it."
|
||||
- "Here's an example:\n```python\ndef add(a, b):\n return a + b\n\nresult = add(3, 4)\nprint(result)\n```"
|
||||
tokens_for_ai: "Explain how to call functions in Python with examples in a friendly and engaging manner."
|
||||
question: "Can you call a function that you've defined and print the result?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You've called the function correctly."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "It seems like you have a partial understanding. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional examples and explanations to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on calling functions."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of calling functions in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The End."
|
||||
content_blocks:
|
||||
- "The End."
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "History Quiz Challenge"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Question 1"
|
||||
content_blocks:
|
||||
- "Welcome to the History Quiz Challenge! 🏆"
|
||||
- "Let's see how well you know your history. Answer the following questions:"
|
||||
question: "Who was the first President of the United States? 🇺🇸"
|
||||
buckets:
|
||||
- george_washington
|
||||
- incorrect
|
||||
transitions:
|
||||
george_washington:
|
||||
content_blocks:
|
||||
- "Correct! George Washington was the first President of the United States."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
incorrect:
|
||||
content_blocks:
|
||||
- "That's not correct. The first President was George Washington."
|
||||
metadata_add:
|
||||
incorrect_attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Question 2"
|
||||
question: "What year did the Titanic sink? 🚢"
|
||||
buckets:
|
||||
- 1912
|
||||
- incorrect
|
||||
transitions:
|
||||
1912:
|
||||
content_blocks:
|
||||
- "Correct! The Titanic sank in 1912."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
incorrect:
|
||||
content_blocks:
|
||||
- "That's not correct. The Titanic sank in 1912."
|
||||
metadata_add:
|
||||
incorrect_attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Question 3"
|
||||
question: "Who painted the Mona Lisa? 🎨"
|
||||
buckets:
|
||||
- leonardo_da_vinci
|
||||
- incorrect
|
||||
transitions:
|
||||
leonardo_da_vinci:
|
||||
content_blocks:
|
||||
- "Correct! Leonardo da Vinci painted the Mona Lisa."
|
||||
metadata_add:
|
||||
correct_answers: "n+1"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
incorrect:
|
||||
content_blocks:
|
||||
- "That's not correct. The Mona Lisa was painted by Leonardo da Vinci."
|
||||
metadata_add:
|
||||
incorrect_attempts: "n+1"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Quiz Results"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Results"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the quiz! 🎉"
|
||||
- "Let's see how you did:"
|
||||
- "Correct Answers: {{correct_answers}}"
|
||||
- "Incorrect Attempts: {{incorrect_attempts}}"
|
||||
question: "Do you want to try the quiz again or exit? Type 'retry' to start over or 'exit' to finish."
|
||||
buckets:
|
||||
- retry
|
||||
- exit
|
||||
transitions:
|
||||
retry:
|
||||
content_blocks:
|
||||
- "Great! Let's start the quiz again. 🏆"
|
||||
metadata_remove:
|
||||
- correct_answers
|
||||
- incorrect_attempts
|
||||
next_section_and_step: "section_1:step_1"
|
||||
exit:
|
||||
content_blocks:
|
||||
- "Thank you for playing the History Quiz Challenge! Have a great day! 🌟"
|
||||
next_section_and_step: "section_3:step_1"
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Goodbye"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Exit"
|
||||
content_blocks:
|
||||
- "Thank you for participating! We hope you enjoyed the quiz. Goodbye! 👋"
|
||||
|
|
@ -1,390 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_0"
|
||||
title: "Introduction"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "Welcome to the Violent Python Mastery course! 🐍"
|
||||
- "This course will test your understanding of key concepts from the book 'Violent Python'."
|
||||
|
||||
- section_id: "section_1"
|
||||
title: "Python for Hackers"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Understanding Python Scripting"
|
||||
content_blocks:
|
||||
- "Python is a powerful tool for hackers due to its simplicity and extensive libraries."
|
||||
- "Think about why Python is favored in the hacking community. Consider aspects like ease of use, versatility, and community support."
|
||||
tokens_for_ai: "Guide the student to think about the reasons Python is popular among hackers. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "Why do you think Python is a popular choice for hackers? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand why Python is popular among hackers. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. Why do you think Python is favored by hackers? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on why Python is popular among hackers. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of Python's popularity in hacking in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Python Libraries for Security"
|
||||
content_blocks:
|
||||
- "Python has many libraries that are useful for security tasks, such as Scapy, Nmap, and PyCrypto."
|
||||
- "Think about how these libraries can be used in security analysis and hacking. Consider aspects like network scanning, packet manipulation, and encryption."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python libraries in security. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python libraries like Scapy and PyCrypto are used in security tasks? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the use of Python libraries in security. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think these libraries are used in security? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the use of Python libraries in security. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of Python libraries in security in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Forensic Analysis with Python"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Python in Forensic Analysis"
|
||||
content_blocks:
|
||||
- "Python can be used in forensic analysis to automate tasks and analyze data."
|
||||
- "Think about how Python scripts can help in forensic investigations. Consider aspects like data parsing, log analysis, and evidence extraction."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python in forensic analysis. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python can be used in forensic analysis? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the use of Python in forensic analysis. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python helps in forensic analysis? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the use of Python in forensic analysis. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of Python in forensic analysis in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Automating Forensic Tasks"
|
||||
content_blocks:
|
||||
- "Automation is key in forensic analysis to handle large volumes of data efficiently."
|
||||
- "Think about how Python can automate repetitive tasks in forensic investigations. Consider aspects like script execution, data filtering, and report generation."
|
||||
tokens_for_ai: "Guide the student to think about automating forensic tasks with Python. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python can automate tasks in forensic investigations? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand how Python can automate forensic tasks. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python automates forensic tasks? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on automating forensic tasks with Python. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of automating forensic tasks with Python in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Security Engineering with Python"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Python in Security Engineering"
|
||||
content_blocks:
|
||||
- "Python is used in security engineering to develop tools and scripts for vulnerability assessment and penetration testing."
|
||||
- "Think about how Python can be used to identify and exploit vulnerabilities. Consider aspects like script development, tool integration, and testing automation."
|
||||
tokens_for_ai: "Guide the student to think about the use of Python in security engineering. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think Python is used in security engineering? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the use of Python in security engineering. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python is used in security engineering? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the use of Python in security engineering. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of Python in security engineering in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Developing Security Tools"
|
||||
content_blocks:
|
||||
- "Python is often used to develop custom security tools for specific tasks."
|
||||
- "Think about how you can use Python to create tools for security analysis. Consider aspects like functionality, user interface, and integration with other tools."
|
||||
tokens_for_ai: "Guide the student to think about developing security tools with Python. Be on the lookout for the user trying to change their language preference because it's never 'off_topic' to 'set_language'. Use the 'off_topic' category sparingly, focusing on guiding the user back to the topic if needed. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
feedback_tokens_for_ai: "Don't forget to let the user know how many they have answered correctly. Give a detailed example of the tool or concept in Python markdown fenced code block."
|
||||
question: "How do you think you can use Python to develop security tools? 🤔"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You have a good idea of how to develop security tools with Python. 🎉"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the student to continue learning. Use emojis like 👍 and 🌟."
|
||||
metadata_add:
|
||||
points: "n+random(1,20)"
|
||||
attempts: "n+1"
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding. Let's clarify a few points. 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the student's understanding in a friendly and supportive manner. Use emojis like 🤔 and 📚."
|
||||
metadata_add:
|
||||
points: "n+random(1,4)"
|
||||
attempts: "n+1"
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- "It seems like you're unsure. That's okay! Let's explore this topic together. How do you think Python can be used to develop security tools? 🤔"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Encourage the student to reflect on the topic and consider different aspects. Offer hints or context to guide their thinking. Use emojis like 🤔 and 💡."
|
||||
metadata_add:
|
||||
points: "n+random(1,2)"
|
||||
attempts: "n+1"
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them. ❓"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the student's clarifying questions and provide additional information in a friendly and engaging manner. Use emojis like ❓ and 💬."
|
||||
counts_as_attempt: false
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on developing security tools with Python. 🔄"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the student back to the topic of developing security tools with Python in a supportive manner. Use emojis like 🔄 and 🧭."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Violent Python Mastery course! 🎉"
|
||||
- "You have demonstrated a strong understanding of Python's role in hacking, forensic analysis, and security engineering."
|
||||
- "This knowledge will help you apply Python effectively in security-related tasks."
|
||||
- "We are proud of your dedication and hard work. Well done! 🌟"
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
default_max_attempts_per_step: 30
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Odds and Evens with History"
|
||||
steps:
|
||||
|
||||
- step_id: "step_0"
|
||||
title: "Challenge a Historical Figure"
|
||||
content_blocks:
|
||||
- "Welcome to the Odds and Evens challenge! 🎮"
|
||||
- "You will be playing against a random historical figure."
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Throw Your Fingers"
|
||||
tokens_for_ai: |
|
||||
Careful to check if user is trying to 'set_language' and do that first. Otherwise, figure out if they are picking a number between 0 and 5.
|
||||
feedback_tokens_for_ai: |
|
||||
Important, you do not have to calculate the winner, we have
|
||||
under processing_script_result for you that determines the winner.
|
||||
|
||||
Important, you do not pick a random move, it was selected for you:
|
||||
|
||||
* 'ai_choice_finger': it's your number of fingers up that you will announce to the user.
|
||||
* 'ai_choice': it's your guess of odd or even that you will announce to the user.
|
||||
|
||||
Speaking in first person as a historical figure, first always announce the move
|
||||
selected for you and then move to a new line.
|
||||
|
||||
The rules are simple, the processing_script_result to determines winner or tie.
|
||||
|
||||
* Sum the numbers.
|
||||
* If the sum of the fingers is even, the player who chose "even" wins.
|
||||
* If the sum is odd, the player who chose "odd" wins.
|
||||
* If both players are wrong or right about "odd" or "even" it's a tie.
|
||||
* A user cannot win unless they have a match with the game name "odd" or "even"
|
||||
|
||||
Careful it's easy to add wrong or say a number is odd when it's even and vice versa.
|
||||
|
||||
Finally, continue to provide a witty fact as the figure. Don't ever mention AI.
|
||||
The figure should also comment on the 'attempts' number and how many times played!
|
||||
If you feel like it, jeer at the player about an early 'exit' & suggest they quit.
|
||||
|
||||
processing_script: |
|
||||
user_input = metadata["user_choice"].split()
|
||||
user_fingers = None
|
||||
user_choice = None
|
||||
for item in user_input:
|
||||
if item.isdigit():
|
||||
user_fingers = int(item)
|
||||
elif item in ["odd", "even"]:
|
||||
user_choice = item
|
||||
ai_fingers = int(metadata["ai_choice_finger"]) # Ensure ai_fingers is an integer
|
||||
ai_choice = metadata["ai_choice"]
|
||||
total_fingers = user_fingers + ai_fingers
|
||||
result = "even" if total_fingers % 2 == 0 else "odd"
|
||||
user_wins = (result == user_choice)
|
||||
ai_wins = (result == ai_choice)
|
||||
if user_wins and not ai_wins:
|
||||
winner = "User wins!"
|
||||
elif ai_wins and not user_wins:
|
||||
winner = "AI wins!"
|
||||
else:
|
||||
winner = "It's a tie!"
|
||||
script_result = {"sum": total_fingers, "result": result, "winner": winner}
|
||||
|
||||
question: "How many fingers do you throw? (Choose a number between 0 and 5 & either even or odd.) 🤔"
|
||||
buckets:
|
||||
- throw_fingers
|
||||
- set_language
|
||||
- exit
|
||||
transitions:
|
||||
throw_fingers:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Declare your move and then determine who wins the game and provide a witty fact from the historical figure's perspective."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
metadata_tmp_add:
|
||||
user_choice: "the-users-response"
|
||||
ai_choice_finger: "n+random(0,5)"
|
||||
metadata_tmp_random:
|
||||
ai_choice: odd
|
||||
ai_choice: even
|
||||
next_section_and_step: "section_1:step_1"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
exit:
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Goodbye"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Exit"
|
||||
content_blocks:
|
||||
- "Thank you for playing! We hope you enjoyed the game. Have a great day! 🌟"
|
||||
|
|
@ -1,373 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Math Quiz: From Basics to Algebra"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Basic Addition"
|
||||
content_blocks:
|
||||
- "Solve the following problem: 5 + 3"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is 5 + 3? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is 8.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_1"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Basic Subtraction"
|
||||
content_blocks:
|
||||
- "Solve the following problem: 10 - 4"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is 10 - 4? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is 6.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Basic Multiplication"
|
||||
content_blocks:
|
||||
- "Solve the following problem: 4 * 2"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is 4 * 2? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is 8.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_4"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_3"
|
||||
|
||||
- step_id: "step_4"
|
||||
title: "Basic Division"
|
||||
content_blocks:
|
||||
- "Solve the following problem: 16 / 4"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is 16 / 4? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is 4.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_5"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_4"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_4"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_4"
|
||||
|
||||
- step_id: "step_5"
|
||||
title: "Introduction to Variables"
|
||||
content_blocks:
|
||||
- "Solve for x: x + 5 = 10"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is the value of x in the equation x + 5 = 10? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is x = 5.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer for x. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_6"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_5"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_5"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_5"
|
||||
|
||||
- step_id: "step_6"
|
||||
title: "Solving Linear Equations"
|
||||
content_blocks:
|
||||
- "Solve for x: 2x + 3 = 11"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is the value of x in the equation 2x + 3 = 11? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is x = 4.
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great job! You got the correct answer for x. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_7"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_6"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_6"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_6"
|
||||
|
||||
- step_id: "step_7"
|
||||
title: "Quadratic Equations"
|
||||
content_blocks:
|
||||
- "Solve the quadratic equation: x^2 - 5x + 6 = 0"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What are the values of x in the equation x^2 - 5x + 6 = 0? Show your work and provide the answers."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answers are x = 2 and x = 3.
|
||||
If the user shows their work but doesn't provide final answers, categorize as 'show_work'.
|
||||
If the answers are incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Well done! You found the correct roots of the equation. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_1:step_8"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_7"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_7"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_7"
|
||||
|
||||
- step_id: "step_8"
|
||||
title: "Simplifying Expressions"
|
||||
content_blocks:
|
||||
- "Simplify the expression: 3(x + 2) - 4x"
|
||||
- "You can show your work and provide the final answer."
|
||||
question: "What is the simplified form of the expression 3(x + 2) - 4x? Show your work and provide the answer."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is correct by checking if the final answer is: 6 - x or -x + 6
|
||||
If the user shows their work but doesn't provide a final answer, categorize as 'show_work'.
|
||||
If the answer is incorrect, categorize as 'incorrect'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT answer or solve the question problem when explaining the problem. Instead use a different contrived problem.
|
||||
buckets:
|
||||
- correct
|
||||
- incorrect
|
||||
- show_work
|
||||
- set_language
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Excellent! You simplified the expression correctly. if 'correct' give the answer and solve the question problem showing all work and explain the problem."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
incorrect:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "The answer is not right. Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
next_section_and_step: "section_1:step_8"
|
||||
show_work:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Thanks the user for showing work. Catch mistakes and suggest next steps. Remember give a separate example to show how to solve the answer, never reveal it."
|
||||
metadata_add:
|
||||
user_work: "the-users-response"
|
||||
next_section_and_step: "section_1:step_8"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_8"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Quiz Complete"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Completion"
|
||||
content_blocks:
|
||||
- "Congratulations! You've completed the math quiz."
|
||||
- "Your final score will be displayed at the end."
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
|
||||
# Common processing script for all plotting steps
|
||||
common_processing_script: &plotting_script |
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot
|
||||
import numpy
|
||||
import io
|
||||
import base64
|
||||
import re
|
||||
import sympy as sp
|
||||
|
||||
# Get the user's function input from metadata
|
||||
user_function = metadata.get("user_function", "x")
|
||||
original_function = user_function
|
||||
|
||||
try:
|
||||
# Support multiple functions separated by semicolon or comma
|
||||
function_list = re.split(r'[;,]', user_function)
|
||||
function_list = [f.strip() for f in function_list if f.strip()]
|
||||
|
||||
# Colors for multiple functions
|
||||
colors = ['blue', 'red', 'green', 'orange', 'purple', 'brown', 'pink', 'gray']
|
||||
|
||||
matplotlib.pyplot.figure(figsize=(10, 6))
|
||||
|
||||
all_y_values = []
|
||||
function_info = []
|
||||
|
||||
for i, func_str in enumerate(function_list):
|
||||
# Preprocess each function
|
||||
processed_func = func_str.replace('^', '**')
|
||||
processed_func = re.sub(r'(?<=\d)(?=[a-zA-Z])', '*', processed_func)
|
||||
processed_func = re.sub(r'(?<=[a-zA-Z])(?=\d)', '*', processed_func)
|
||||
|
||||
# Enhanced function preprocessing
|
||||
enhanced_replacements = {
|
||||
'arctan': 'atan',
|
||||
'arcsin': 'asin',
|
||||
'arccos': 'acos',
|
||||
'log': 'ln',
|
||||
'ln': 'log', # Allow both ln and log
|
||||
'abs': 'Abs'
|
||||
}
|
||||
|
||||
parsed_function = processed_func
|
||||
for old, new in enhanced_replacements.items():
|
||||
parsed_function = re.sub(r'\b' + old + r'\b', new, parsed_function)
|
||||
|
||||
# Create sympy symbol and parse expression
|
||||
x_sym = sp.Symbol('x')
|
||||
expr = sp.sympify(parsed_function, locals={'x': x_sym})
|
||||
|
||||
# Analyze function characteristics for dynamic range (inline)
|
||||
func_type = "other"
|
||||
if expr.has(sp.sin) or expr.has(sp.cos) or expr.has(sp.tan):
|
||||
func_type = "trigonometric"
|
||||
elif expr.has(sp.exp):
|
||||
func_type = "exponential"
|
||||
elif expr.has(sp.log):
|
||||
func_type = "logarithmic"
|
||||
elif expr.is_polynomial(x_sym):
|
||||
degree = sp.degree(expr, x_sym)
|
||||
if degree == 1:
|
||||
func_type = "linear"
|
||||
elif degree == 2:
|
||||
func_type = "quadratic"
|
||||
elif degree == 3:
|
||||
func_type = "cubic"
|
||||
elif expr.has(sp.sqrt):
|
||||
func_type = "radical"
|
||||
elif expr.has(1/x_sym):
|
||||
func_type = "rational"
|
||||
|
||||
# Determine optimal range inline
|
||||
if func_type == "trigonometric":
|
||||
x_range = (-2*numpy.pi, 2*numpy.pi)
|
||||
elif func_type == "exponential":
|
||||
x_range = (-3, 3)
|
||||
elif func_type == "logarithmic":
|
||||
x_range = (0.1, 10)
|
||||
elif func_type in ["linear", "quadratic", "cubic"]:
|
||||
x_range = (-10, 10)
|
||||
elif func_type == "rational":
|
||||
x_range = (-10, 10)
|
||||
else:
|
||||
x_range = (-5, 5)
|
||||
|
||||
# Prepare x values with dynamic range
|
||||
x_vals = numpy.linspace(x_range[0], x_range[1], 400)
|
||||
|
||||
# Convert to numpy function and evaluate
|
||||
func = sp.lambdify(x_sym, expr, 'numpy')
|
||||
y = func(x_vals)
|
||||
|
||||
# Handle complex results
|
||||
if numpy.iscomplexobj(y):
|
||||
y = numpy.real(y)
|
||||
|
||||
# Filter out infinite/NaN values for better plotting
|
||||
valid_mask = numpy.isfinite(y)
|
||||
x_vals_clean = x_vals[valid_mask]
|
||||
y_clean = y[valid_mask]
|
||||
|
||||
if len(y_clean) > 0:
|
||||
all_y_values.extend(y_clean)
|
||||
color = colors[i % len(colors)]
|
||||
matplotlib.pyplot.plot(x_vals_clean, y_clean,
|
||||
label=f'y = {func_str}',
|
||||
color=color, linewidth=2)
|
||||
|
||||
# Store function analysis info
|
||||
function_info.append({
|
||||
'function': func_str,
|
||||
'type': func_type,
|
||||
'range': x_range
|
||||
})
|
||||
|
||||
# Dynamic y-axis limits based on all functions
|
||||
if all_y_values:
|
||||
y_min, y_max = numpy.percentile(all_y_values, [5, 95])
|
||||
y_range = y_max - y_min
|
||||
matplotlib.pyplot.ylim(y_min - 0.1*y_range, y_max + 0.1*y_range)
|
||||
|
||||
# Enhanced plot styling
|
||||
matplotlib.pyplot.title(f'Plot of: {original_function}', fontsize=14, fontweight='bold')
|
||||
matplotlib.pyplot.xlabel('x', fontsize=12)
|
||||
matplotlib.pyplot.ylabel('y', fontsize=12)
|
||||
matplotlib.pyplot.grid(True, alpha=0.3)
|
||||
matplotlib.pyplot.legend(fontsize=10)
|
||||
|
||||
# Generate function analysis inline
|
||||
analysis_parts = []
|
||||
for info in function_info:
|
||||
func_type = info['type']
|
||||
if func_type == "quadratic":
|
||||
analysis_parts.append(f"'{info['function']}' is a parabola (quadratic function)")
|
||||
elif func_type == "linear":
|
||||
analysis_parts.append(f"'{info['function']}' is a straight line (linear function)")
|
||||
elif func_type == "trigonometric":
|
||||
analysis_parts.append(f"'{info['function']}' shows periodic behavior (trigonometric)")
|
||||
elif func_type == "exponential":
|
||||
analysis_parts.append(f"'{info['function']}' shows exponential growth/decay")
|
||||
elif func_type == "logarithmic":
|
||||
analysis_parts.append(f"'{info['function']}' is a logarithmic curve")
|
||||
else:
|
||||
analysis_parts.append(f"'{info['function']}' is a {func_type} function")
|
||||
|
||||
analysis_text = "; ".join(analysis_parts)
|
||||
|
||||
buf = io.BytesIO()
|
||||
matplotlib.pyplot.tight_layout()
|
||||
matplotlib.pyplot.savefig(buf, format='png', dpi=100, bbox_inches='tight')
|
||||
matplotlib.pyplot.close()
|
||||
buf.seek(0)
|
||||
plot_image = base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
script_result = {
|
||||
"plot_image": plot_image,
|
||||
"function_analysis": analysis_text,
|
||||
"function_info": function_info
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
# Handle errors gracefully with error message plot
|
||||
matplotlib.pyplot.figure()
|
||||
matplotlib.pyplot.text(0.5, 0.5, f'Error: Invalid function\n"{original_function}"\n\n{str(e)[:100]}...',
|
||||
horizontalalignment='center', verticalalignment='center',
|
||||
transform=matplotlib.pyplot.gca().transAxes, fontsize=12,
|
||||
bbox=dict(boxstyle="round,pad=0.3", facecolor="lightcoral"))
|
||||
matplotlib.pyplot.title('Function Error')
|
||||
matplotlib.pyplot.axis('off')
|
||||
buf = io.BytesIO()
|
||||
matplotlib.pyplot.savefig(buf, format='png')
|
||||
matplotlib.pyplot.close()
|
||||
buf.seek(0)
|
||||
plot_image = base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
script_result = {"plot_image": plot_image, "error": str(e)}
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Math Plotter: Visualizing Functions"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Introduction to Plotting"
|
||||
content_blocks:
|
||||
- "Welcome to the Math Plotter activity! 📈"
|
||||
- "In this activity, you'll learn how to plot mathematical functions and visualize them."
|
||||
question: "Are you ready to start plotting? Type 'yes' to begin."
|
||||
tokens_for_ai: |
|
||||
Determine if the user's response is 'yes' to proceed.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
buckets:
|
||||
- proceed
|
||||
- set_language
|
||||
transitions:
|
||||
proceed:
|
||||
next_section_and_step: "section_1:step_2"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_1"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "First Plot - Linear Function"
|
||||
content_blocks:
|
||||
- "Let's start by plotting a specific linear function! 📏"
|
||||
- "We'll plot: y = 2*x + 1"
|
||||
question: "Ready to plot y = 2*x + 1? Type 'yes' to see the graph."
|
||||
tokens_for_ai: |
|
||||
Check if the user entered a valid linear function. Accept any linear function like 'mx + b' format.
|
||||
Don't require analysis at this step - just check if it's a valid function.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
processing_script: *plotting_script
|
||||
|
||||
buckets:
|
||||
- proceed
|
||||
- set_language
|
||||
transitions:
|
||||
proceed:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Perfect! Here's the linear function y = 2*x + 1 plotted for you. Now you can explore plotting any functions you want!"
|
||||
metadata_add:
|
||||
user_function: "2*x + 1"
|
||||
next_section_and_step: "section_1:step_3"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Free Exploration - Plot Anything!"
|
||||
content_blocks:
|
||||
- "🎨 Time to explore! You can plot any function(s) you want."
|
||||
- "Try single functions: x**2, sin(x), exp(x), log(x), sqrt(x)"
|
||||
- "Try multiple functions: sin(x), cos(x) or x**2, 2*x + 1"
|
||||
- "Mix different types: sin(x), x**2, exp(-x)"
|
||||
- "Type 'done' when you're ready to finish."
|
||||
question: "Enter any function(s) to plot (or 'done' to complete):"
|
||||
tokens_for_ai: |
|
||||
This is a free exploration step. Accept any valid mathematical function(s).
|
||||
If user says 'done', 'finished', 'complete', etc., categorize as 'done'.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
Otherwise, if it looks like a valid function, categorize as 'valid_function'.
|
||||
processing_script: *plotting_script
|
||||
|
||||
buckets:
|
||||
- valid_function
|
||||
- done
|
||||
- invalid_function
|
||||
- set_language
|
||||
transitions:
|
||||
valid_function:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great exploration! Here's your plot. Try another function or type 'done' to finish."
|
||||
metadata_add:
|
||||
user_function: "the-users-response"
|
||||
exploration_count: "n+1"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_3"
|
||||
done:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Excellent exploration! You've completed the math plotting activity."
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: "section_2:step_1"
|
||||
invalid_function:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "That doesn't look like a valid function. Try mathematical expressions like 'x**2' or 'sin(x)'."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_3"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_3"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Plotting Complete"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Completion"
|
||||
content_blocks:
|
||||
- "Congratulations! You've completed the math plotter activity."
|
||||
- "You've learned how to plot and visualize different types of functions."
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
default_max_attempts_per_step: 1
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Magic 8 Ball"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- "Welcome to the Magic 8 Ball! 🎱"
|
||||
- "Think of a yes or no question and ask the Magic 8 Ball."
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Ask the Magic 8 Ball"
|
||||
question: "What is your question for the Magic 8 Ball?"
|
||||
tokens_for_ai: |
|
||||
Provide a random response from the Magic 8 Ball's set of answers.
|
||||
If the user wants to change the language, categorize as 'set_language'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
feedback_tokens_for_ai: |
|
||||
Use the user's question to provide a random Magic 8 Ball response.
|
||||
Consider the tone and style of traditional Magic 8 Ball answers.
|
||||
buckets:
|
||||
- ask_question
|
||||
- set_language
|
||||
- exit
|
||||
transitions:
|
||||
ask_question:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Your answer for the user is in the metadata.
|
||||
Use the user's question to provide a random Magic 8 Ball response.
|
||||
Use emoji at the end of the response to relate.
|
||||
On a new line write two sentences making a joke or relating to the question and the result.
|
||||
metadata_tmp_random:
|
||||
magic_8_ball_response:
|
||||
# Positive answers
|
||||
- "It is certain."
|
||||
- "Without a doubt."
|
||||
- "You may rely on it."
|
||||
- "Yes, definitely."
|
||||
- "As I see it, yes."
|
||||
- "Most likely."
|
||||
- "Outlook good."
|
||||
- "Yes."
|
||||
- "Signs point to yes."
|
||||
- "Absolutely."
|
||||
# Negative answers
|
||||
- "Don't count on it."
|
||||
- "My reply is no."
|
||||
- "My sources say no."
|
||||
- "Outlook not so good."
|
||||
- "Very doubtful."
|
||||
# Vague answers
|
||||
- "Reply hazy, try again."
|
||||
- "Ask again later."
|
||||
- "Better not tell you now."
|
||||
- "Cannot predict now."
|
||||
- "Concentrate and ask again."
|
||||
next_section_and_step: "section_1:step_1"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "section_1:step_1"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Goodbye"
|
||||
content_blocks:
|
||||
- "Thank you for playing with the Magic 8 Ball! 🎉"
|
||||
- "Feel free to come back anytime to ask more questions."
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
default_max_attempts_per_step: 9
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Tic Tac Toe"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- |
|
||||
Welcome to Tic Tac Toe! 🎮
|
||||
You will be playing against the AI. You are 'X' and the AI is 'O'.
|
||||
The board positions are numbered 0 to 8 as follows:
|
||||
|
||||
<img src="/static/images/tic-tac-toe.png">
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Your Move"
|
||||
question: "Enter a position number (0-8) to place your 'X'. Say restart or exit to quit."
|
||||
tokens_for_ai: |
|
||||
Using the metadata, determine if the game is over and 'restart'.
|
||||
If the user wants to restart or play again, categorize as 'restart'
|
||||
If ai_wins or user_wins or is_draw is true, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
If the game_over is True categorize as 'restart'.
|
||||
Finally check:
|
||||
If the move is valid, categorize as 'valid_move'.
|
||||
If the move is invalid, categorize as 'invalid_move'.
|
||||
feedback_tokens_for_ai: |
|
||||
Always speak in first person. DO NOT START WITH "ai_move:".
|
||||
Player is always X, You the AI are always O.
|
||||
If there is an error in the metadata the move was likely invalid.
|
||||
On a new line, provide feedback on the user's move.
|
||||
Only announce a winner or tie if game_over is True.
|
||||
The player makes the first and last move.
|
||||
If the move is invalid, prompt the user to try again.
|
||||
If the move is invalid, give a list of valid moves.
|
||||
If the move is valid & no errors say your move on the last line (ai_move) for example: I move to 8 and draw a O".
|
||||
processing_script: |
|
||||
import random
|
||||
|
||||
win_conditions = [
|
||||
[0, 1, 2], [3, 4, 5], [6, 7, 8], # rows
|
||||
[0, 3, 6], [1, 4, 7], [2, 5, 8], # columns
|
||||
[0, 4, 8], [2, 4, 6] # diagonals
|
||||
]
|
||||
|
||||
def check_win(board, player, win_conditions):
|
||||
# Check for win and return the winning condition if there is one
|
||||
for condition in win_conditions:
|
||||
win = True
|
||||
for i in condition:
|
||||
if board[i] != player:
|
||||
win = False
|
||||
break
|
||||
if win:
|
||||
return condition
|
||||
return None
|
||||
|
||||
def plot_board(board, win_line=None):
|
||||
import io
|
||||
import base64
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
fig, ax = plt.subplots(figsize=(3, 3))
|
||||
ax.set_xlim(0, 3)
|
||||
ax.set_ylim(0, 3)
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
ax.grid(True)
|
||||
|
||||
for i, mark in enumerate(board):
|
||||
x = i % 3
|
||||
y = 2 - i // 3
|
||||
if mark != " ":
|
||||
ax.text(x + 0.5, y + 0.5, mark, fontsize=24, ha='center', va='center')
|
||||
else:
|
||||
# Plot the cell number if the cell is empty
|
||||
ax.text(x + 0.5, y + 0.5, str(i), fontsize=12, ha='center', va='center', color='gray')
|
||||
|
||||
|
||||
# Draw the winning line if there is one
|
||||
if win_line:
|
||||
for i in range(len(win_line) - 1):
|
||||
start = win_line[i]
|
||||
end = win_line[i + 1]
|
||||
x_start, y_start = start % 3 + 0.5, 2 - start // 3 + 0.5
|
||||
x_end, y_end = end % 3 + 0.5, 2 - end // 3 + 0.5
|
||||
ax.plot([x_start, x_end], [y_start, y_end], 'r-', linewidth=2)
|
||||
|
||||
buf = io.BytesIO()
|
||||
plt.savefig(buf, format='png')
|
||||
plt.close(fig)
|
||||
buf.seek(0)
|
||||
return base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
# Reconstruct the board from moves
|
||||
user_moves = metadata.get("user_moves", [])
|
||||
ai_moves = metadata.get("ai_moves", [])
|
||||
ai_move = None
|
||||
board = [" "] * 9
|
||||
for move in user_moves:
|
||||
board[int(move)] = "X"
|
||||
for move in ai_moves:
|
||||
board[int(move)] = "O"
|
||||
|
||||
# Get the user's latest move
|
||||
try:
|
||||
user_move = int(metadata.get("user_move"))
|
||||
except (IndexError, ValueError) as e:
|
||||
# Remove the invalid move from user_moves
|
||||
user_move = -1
|
||||
|
||||
# Check if the move is valid
|
||||
if 0 <= user_move < 9 and board[user_move] == " ":
|
||||
board[user_move] = "X"
|
||||
user_moves.append(user_move)
|
||||
|
||||
user_win_line = check_win(board, "X", win_conditions)
|
||||
|
||||
if not user_win_line:
|
||||
# ai makes a move.
|
||||
available_positions = []
|
||||
for i in range(len(board)):
|
||||
if board[i] == " ":
|
||||
available_positions.append(i)
|
||||
if available_positions:
|
||||
ai_move = random.choice(available_positions)
|
||||
board[ai_move] = "O"
|
||||
ai_moves.append(ai_move)
|
||||
|
||||
ai_win_line = check_win(board, "O", win_conditions)
|
||||
is_draw = True
|
||||
for x in board:
|
||||
if x == " ":
|
||||
is_draw = False
|
||||
break
|
||||
game_over = any([user_win_line, ai_win_line, is_draw])
|
||||
|
||||
win_line = user_win_line if user_win_line else ai_win_line
|
||||
|
||||
script_result = {
|
||||
"plot_image": plot_board(board, win_line),
|
||||
"set_background": not game_over,
|
||||
"ai_move": ai_move,
|
||||
"user_move": user_move,
|
||||
"metadata": {
|
||||
"user_moves": user_moves,
|
||||
"ai_moves": ai_moves,
|
||||
"board": board,
|
||||
"game_over": game_over,
|
||||
"ai_wins": ai_win_line is not None,
|
||||
"user_wins": user_win_line is not None,
|
||||
"is_draw": is_draw
|
||||
}
|
||||
}
|
||||
else:
|
||||
script_result = {
|
||||
"error": f"Invalid move: {metadata.get('user_move')}",
|
||||
"metadata": {
|
||||
"user_moves": user_moves,
|
||||
},
|
||||
}
|
||||
|
||||
# Debugging: Print the current board state
|
||||
print("Current board state:", board)
|
||||
|
||||
buckets:
|
||||
- valid_move
|
||||
- invalid_move
|
||||
- restart
|
||||
- exit
|
||||
transitions:
|
||||
valid_move:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
at first glance it seems like a valid user_move.
|
||||
DO NOT:
|
||||
* DRAW THE GAME BOARD
|
||||
* DESCRIBE THE GAME BOARD
|
||||
metadata_tmp_add:
|
||||
user_move: "the-users-response"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
invalid_move:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "That move is invalid. Please choose an empty position between 0 and 8."
|
||||
metadata_tmp_add:
|
||||
user_move: "the-users-response"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_2"
|
||||
restart:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Goodbye"
|
||||
content_blocks:
|
||||
- "Thank you for playing Tic Tac Toe! 🎉"
|
||||
- "Feel free to come back anytime for another game."
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
default_max_attempts_per_step: 9
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Killer Squares"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- |
|
||||
Welcome to Killer Squares! 🎮
|
||||
In this game, both you and the AI will secretly choose a square.
|
||||
Then, you will attempt to "kill" a square. If you hit the AI's secret spot, you win!
|
||||
If the AI hits your secret spot, you lose. If nobody hits, the game continues.
|
||||
|
||||
The board positions are numbered 0 to 8 as follows:
|
||||
|
||||
```
|
||||
0 | 1 | 2
|
||||
---------
|
||||
3 | 4 | 5
|
||||
---------
|
||||
6 | 7 | 8
|
||||
```
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Choose Your Secret Spot"
|
||||
question: "Choose a secret spot (0-8) for this round."
|
||||
tokens_for_ai: |
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
If the move is valid, categorize as 'valid_move'.
|
||||
If the move is invalid, categorize as 'invalid_move'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT TELL THE AI SECRET.
|
||||
If there is an error in the metadata the move was likely invalid.
|
||||
Always speak in first person. DO NOT START WITH "ai_move:".
|
||||
On a new line, provide feedback on the user's move.
|
||||
If the move is valid, proceed to the next step.
|
||||
If the move is invalid, prompt the user to try again.
|
||||
processing_script: |
|
||||
import random
|
||||
|
||||
# Initialize or retrieve the game state
|
||||
user_secret = metadata.get("user_secret", None)
|
||||
ai_secret = random.randint(0, 8)
|
||||
|
||||
# Get the user's secret spot
|
||||
try:
|
||||
user_secret = int(metadata.get("user_secret"))
|
||||
except (IndexError, ValueError) as e:
|
||||
user_secret = -1
|
||||
|
||||
# Check if the move is valid
|
||||
if 0 <= user_secret < 9:
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"user_secret": user_secret,
|
||||
"ai_secret": ai_secret,
|
||||
}
|
||||
}
|
||||
else:
|
||||
script_result = {
|
||||
"error": f"Invalid secret spot: {metadata.get('user_secret')}",
|
||||
"metadata": {}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- valid_move
|
||||
- invalid_move
|
||||
- restart
|
||||
- exit
|
||||
transitions:
|
||||
valid_move:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "You've chosen your secret spot. Now, let's move to the killing round."
|
||||
metadata_add:
|
||||
user_secret: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
invalid_move:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "That move is invalid. Please choose a position between 0 and 8."
|
||||
metadata_add:
|
||||
user_secret: "the-users-response"
|
||||
next_section_and_step: "section_1:step_1"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_3"
|
||||
restart:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Kill a Square"
|
||||
question: "Choose a square to kill (0-8)."
|
||||
tokens_for_ai: |
|
||||
If the user wants to restart or play again, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
If the move is valid, categorize as 'valid_move'.
|
||||
If the move is invalid, categorize as 'invalid_move'.
|
||||
feedback_tokens_for_ai: |
|
||||
DO NOT reveal the AI's secret spot until game_over = True.
|
||||
ALWAYS speak in first person. DO NOT START WITH "ai_move:".
|
||||
If there is an error in the metadata, the move was likely invalid.
|
||||
On a new line, provide feedback on the user's move:
|
||||
- If the move is valid, check if the user's shot hit my (AI's) secret spot (ai_secret).
|
||||
- If the user's shot hits my secret spot, say: "You hit my secret spot!"
|
||||
- If the user's shot misses, say: "You missed my secret spot."
|
||||
If the move is invalid, prompt the user to try again.
|
||||
My move is the last item in the ai_shots list. For example, if ai_shots = [5, 3], my move is 3.
|
||||
Announce my move: "I shoot at position [my move]."
|
||||
If game_over = True, determine the winner:
|
||||
- If user_wins = True, say: "Congratulations! You hit my secret spot and won the round!"
|
||||
- If ai_wins = True, say: "I hit your secret spot and won the round!"
|
||||
If game_over = True, describe the carnage of the final strike.
|
||||
If game_over = True, suggest: "Would you like to restart and play again, or would you prefer to exit?"
|
||||
processing_script: |
|
||||
import random
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
import io
|
||||
import base64
|
||||
|
||||
# Retrieve the game state
|
||||
user_secret = metadata.get("user_secret")
|
||||
ai_secret = metadata.get("ai_secret")
|
||||
user_shots = metadata.get("user_shots", [])
|
||||
ai_shots = metadata.get("ai_shots", [])
|
||||
game_over = metadata.get("game_over", False)
|
||||
|
||||
|
||||
# Get the user's kill move
|
||||
try:
|
||||
user_kill = int(metadata.get("user_kill"))
|
||||
except (IndexError, ValueError) as e:
|
||||
user_kill = -1
|
||||
|
||||
if game_over:
|
||||
script_result = {}
|
||||
elif 0 <= user_kill < 9:
|
||||
# the move is valid.
|
||||
user_shots.append(user_kill)
|
||||
if user_kill == ai_secret:
|
||||
game_over = True
|
||||
user_wins = True
|
||||
ai_wins = False
|
||||
draw = False
|
||||
user_title = "You Win!"
|
||||
ai_title = "AI's Moves"
|
||||
else:
|
||||
# AI makes a move, avoiding its own secret spot
|
||||
available_positions = []
|
||||
for i in range(9):
|
||||
if i not in ai_shots and i != ai_secret:
|
||||
available_positions.append(i)
|
||||
ai_kill = random.choice(available_positions) if available_positions else None
|
||||
if ai_kill is not None:
|
||||
ai_shots.append(ai_kill)
|
||||
if ai_kill == user_secret:
|
||||
game_over = True
|
||||
user_wins = False
|
||||
ai_wins = True
|
||||
draw = False
|
||||
user_title = "Your Moves"
|
||||
ai_title = "AI Wins!"
|
||||
else:
|
||||
game_over = False
|
||||
user_wins = False
|
||||
ai_wins = False
|
||||
draw = False
|
||||
user_title = "Your Moves"
|
||||
ai_title = "AI's Moves"
|
||||
else:
|
||||
game_over = True
|
||||
user_wins = False
|
||||
ai_wins = False
|
||||
draw = True
|
||||
user_title = "Your Moves"
|
||||
ai_title = "It's a Draw!"
|
||||
|
||||
# Plot the boards
|
||||
fig, axs = plt.subplots(1, 2, figsize=(6, 3))
|
||||
fig.suptitle("Killer Squares", fontsize=16)
|
||||
fig.tight_layout(h_pad=4)
|
||||
|
||||
# User's board
|
||||
axs[0].set_xlim(0, 3)
|
||||
axs[0].set_ylim(0, 3)
|
||||
axs[0].set_xticks([])
|
||||
axs[0].set_yticks([])
|
||||
axs[0].grid(True)
|
||||
axs[0].set_title(user_title, fontsize=12)
|
||||
|
||||
for i in range(9):
|
||||
x = i % 3
|
||||
y = 2 - i // 3
|
||||
axs[0].text(x + 0.5, y + 0.5, str(i), fontsize=12, ha='center', va='center', color='gray')
|
||||
|
||||
for user_kill in user_shots:
|
||||
ux, uy = user_kill % 3, 2 - user_kill // 3
|
||||
axs[0].text(ux + 0.5, uy + 0.5, 'X', fontsize=24, ha='center', va='center', color='red')
|
||||
|
||||
# AI's board
|
||||
axs[1].set_xlim(0, 3)
|
||||
axs[1].set_ylim(0, 3)
|
||||
axs[1].set_xticks([])
|
||||
axs[1].set_yticks([])
|
||||
axs[1].grid(True)
|
||||
axs[1].set_title(ai_title, fontsize=12)
|
||||
|
||||
for i in range(9):
|
||||
x = i % 3
|
||||
y = 2 - i // 3
|
||||
axs[1].text(x + 0.5, y + 0.5, str(i), fontsize=12, ha='center', va='center', color='gray')
|
||||
|
||||
for ai_kill in ai_shots:
|
||||
axx, axy = ai_kill % 3, 2 - ai_kill // 3
|
||||
axs[1].text(axx + 0.5, axy + 0.5, 'X', fontsize=24, ha='center', va='center', color='blue')
|
||||
|
||||
buf = io.BytesIO()
|
||||
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.1)
|
||||
plt.close(fig)
|
||||
buf.seek(0)
|
||||
plot_image = base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
script_result = {
|
||||
"plot_image": plot_image,
|
||||
"metadata": {
|
||||
"user_secret": user_secret,
|
||||
"ai_secret": ai_secret,
|
||||
"user_shots": user_shots,
|
||||
"ai_shots": ai_shots,
|
||||
"game_over": game_over,
|
||||
"user_wins": user_wins,
|
||||
"ai_wins": ai_wins,
|
||||
"draw": draw,
|
||||
}
|
||||
}
|
||||
else:
|
||||
script_result = {
|
||||
"error": f"Invalid kill move: {metadata.get('user_kill')}",
|
||||
"metadata": {}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- valid_move
|
||||
- invalid_move
|
||||
- exit
|
||||
- restart
|
||||
transitions:
|
||||
valid_move:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
If somebody wins explain the move that triggered the kill shot.
|
||||
Only if game_over is True reveal the ai secret spot number otherwise never tell the player the secret!
|
||||
metadata_tmp_add:
|
||||
user_kill: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
invalid_move:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "That move is invalid. Please choose a position between 0 and 8."
|
||||
metadata_tmp_add:
|
||||
user_kill: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_3"
|
||||
restart:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Goodbye"
|
||||
content_blocks:
|
||||
- "Thank you for playing Killer Squares! 🎉"
|
||||
- "Feel free to come back anytime for another game."
|
||||
|
|
@ -1,924 +0,0 @@
|
|||
default_max_attempts_per_step: 9
|
||||
tokens_for_ai_rubric: |
|
||||
based on the game without knowing where each ship was, score the process each player used to target ships.
|
||||
|
||||
be sure to look for moves or strategies in the game play that where _not_ smart given the obvious information uncovered.
|
||||
|
||||
use chain-of-thought to reason about the progression of the game and the winner.
|
||||
|
||||
first summarize the game, we don't need the turn by turn plays.
|
||||
|
||||
the game was battleship. the moves were done 1 by 1.
|
||||
the grid is 0-99.
|
||||
|
||||
did any player blunder as the information was learned?
|
||||
|
||||
There was a user and an AI playing.
|
||||
|
||||
Depending on the game mode the player chooses they are going up against a different algo,
|
||||
|
||||
* random
|
||||
|
||||
* always plays randomly
|
||||
|
||||
* hunter
|
||||
|
||||
* keeps track of hits and targets every cell around it no matter what, randomly, else random
|
||||
|
||||
* super human hunter
|
||||
|
||||
* keeps track of hits and uses a probability grid normalized to 100 and always picks the max or random of any 100.
|
||||
|
||||
* hermes reasoner
|
||||
|
||||
* uses the probability algorithm paired with hermes to reason for 3 sentences about what the next 0-99 move should be given the current game state and turn number
|
||||
|
||||
Did any player miss sinking a ship that was found? was it due to end game or a blunder?
|
||||
|
||||
Do not mix up ships, keep careful track of the order they were found and sunk.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Battleship"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- |
|
||||
Welcome to Battleship! 🚢
|
||||
In this game, both you and the AI have a fleet of ships placed randomly on a 10x10 grid.
|
||||
The grid positions are numbered 0 to 99.
|
||||
|
||||
Your goal is to sink all of the AI's ships before it sinks yours.
|
||||
Let's get started!
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Choose AI Mode"
|
||||
question: "Choose the AI mode: Random, Hunter, Super Human Hunter, or Hermes Reasoner?"
|
||||
tokens_for_ai: |
|
||||
If the user chooses Random, categorize as 'random_mode'.
|
||||
If the user chooses Hunter, categorize as 'hunter_mode'.
|
||||
If the user chooses Super Human Hunter, categorize as 'super_hunter_mode'.
|
||||
If the user chooses Hermes Reasoner, categorize as 'hermes_reasoner_mode'.
|
||||
feedback_tokens_for_ai: |
|
||||
If the user chooses Random, say: "Random mode selected! The AI will make completely random moves."
|
||||
If the user chooses Hunter, say: "Hunter mode selected! The AI will systematically hunt around hits."
|
||||
If the user chooses Super Human Hunter, say: "Super Human Hunter mode selected! The AI will use advanced probability analysis."
|
||||
If the user chooses Hermes Reasoner, say: "Hermes Reasoner mode selected! The AI will use probability analysis combined with reasoning to make strategic decisions."
|
||||
processing_script: |
|
||||
import random
|
||||
|
||||
def place_ships():
|
||||
global random
|
||||
# Define ship sizes and names
|
||||
ships = {
|
||||
"Carrier": 5,
|
||||
"Battleship": 4,
|
||||
"Cruiser": 3,
|
||||
"Submarine": 3,
|
||||
"Destroyer": 2
|
||||
}
|
||||
|
||||
board = [-1] * 100
|
||||
for ship, size in ships.items():
|
||||
placed = False
|
||||
while not placed:
|
||||
orientation = random.choice(['horizontal', 'vertical'])
|
||||
if orientation == 'horizontal':
|
||||
row = random.randint(0, 9)
|
||||
col = random.randint(0, 9 - size)
|
||||
start = row * 10 + col
|
||||
if all(board[start + i] == -1 for i in range(size)):
|
||||
for i in range(size):
|
||||
board[start + i] = ship
|
||||
placed = True
|
||||
else:
|
||||
row = random.randint(0, 9 - size)
|
||||
col = random.randint(0, 9)
|
||||
start = row * 10 + col
|
||||
if all(board[start + i * 10] == -1 for i in range(size)):
|
||||
for i in range(size):
|
||||
board[start + i * 10] = ship
|
||||
placed = True
|
||||
return board
|
||||
|
||||
user_board = place_ships()
|
||||
ai_board = place_ships() # AI also gets randomly placed ships
|
||||
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"user_board": user_board,
|
||||
"ai_board": ai_board
|
||||
}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- random_mode
|
||||
- hunter_mode
|
||||
- super_hunter_mode
|
||||
- hermes_reasoner_mode
|
||||
transitions:
|
||||
random_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Random Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "random"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
hunter_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Hunter Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "hunter"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
super_hunter_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Super Human Hunter Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "super_hunter"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
hermes_reasoner_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Hermes Reasoner Mode enabled for the AI. The AI will use probability analysis combined with reasoning to make strategic decisions."
|
||||
metadata_add:
|
||||
ai_mode: "hermes_reasoner"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Take a Shot"
|
||||
question: "Choose a position to fire at (0-99)."
|
||||
pre_script: |
|
||||
# Check if moves match winning moves from previous turn
|
||||
user_winning_move = metadata.get("user_winning_move")
|
||||
ai_winning_move = metadata.get("ai_winning_move")
|
||||
user_shot_input = metadata.get("user_response", "")
|
||||
# print(f"PRE-SCRIPT DEBUG: user_shot_input = '{user_shot_input}', user_winning_move = {user_winning_move}, ai_winning_move = {ai_winning_move}")
|
||||
ai_shot = metadata.get("ai_shot")
|
||||
|
||||
is_game_ending_move = False
|
||||
|
||||
# Check if user move wins
|
||||
if user_shot_input and user_shot_input.isdigit():
|
||||
user_move = int(user_shot_input)
|
||||
if user_winning_move is not None and user_move == user_winning_move:
|
||||
is_game_ending_move = True
|
||||
# print(f"PRE-SCRIPT: User winning move detected! user_move={user_move} matches user_winning_move={user_winning_move}")
|
||||
|
||||
# Check if AI move wins (from previous turn)
|
||||
if ai_shot is not None and ai_winning_move is not None and ai_shot == ai_winning_move:
|
||||
is_game_ending_move = True
|
||||
# print(f"PRE-SCRIPT: AI winning move detected! ai_shot={ai_shot} matches ai_winning_move={ai_winning_move}")
|
||||
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"is_game_ending_move": is_game_ending_move
|
||||
}
|
||||
}
|
||||
tokens_for_ai: |
|
||||
1) If the user reply is *only* digits, and corresponds to a grid cell (0–99),
|
||||
treat it as a valid move:
|
||||
If the response matches the regex /^\d+$/ and 0 ≤ int(response) < 100, categorize as 'valid_move'.
|
||||
|
||||
2) Otherwise fall back to the usual buckets:
|
||||
If the user wants to restart or play again, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
Otherwise, categorize as 'invalid_move'.
|
||||
feedback_tokens_for_ai: |
|
||||
You are a battleship narrator. Each prompt has its own specific role - follow the individual prompt instructions precisely.
|
||||
feedback_prompts:
|
||||
- name: "Shot Report"
|
||||
tokens_for_ai: |
|
||||
🎯 Report ONLY the hit/miss results for both shots this turn. DO NOT report ship sinking or game over.
|
||||
|
||||
Check metadata:
|
||||
- user_shot: Player's target position
|
||||
- user_hit_result: "hit" or "miss"
|
||||
- ai_shot: AI's target position
|
||||
- ai_hit_result: "hit" or "miss"
|
||||
|
||||
Format: "🎯 Your shot at position [user_shot]: [user_hit_result]! 🤖 Enemy shot at position [ai_shot]: [ai_hit_result]!"
|
||||
metadata_filter:
|
||||
- user_shot
|
||||
- ai_shot
|
||||
- user_hit_result
|
||||
- ai_hit_result
|
||||
- user_response
|
||||
|
||||
- name: "Ship Status"
|
||||
tokens_for_ai: |
|
||||
A ship has been destroyed! Generate a dramatic 2-3 sentence description.
|
||||
|
||||
Metadata tells you which ship(s) were sunk:
|
||||
- user_sunk_ship_this_round: The ship YOU destroyed (your victory)
|
||||
- ai_sunk_ship_this_round: The ship that was destroyed by the enemy (your loss)
|
||||
|
||||
Format:
|
||||
- If user destroyed a ship: "💥 You've sunk their [ship]! [2-3 dramatic sentences imagining how this warship meets its doom]"
|
||||
- If AI destroyed your ship: "🔥 Your [ship] has been destroyed! [2-3 dramatic sentences about its destruction]"
|
||||
- If both: Include both messages
|
||||
metadata_filter:
|
||||
- user_sunk_ship_this_round
|
||||
- ai_sunk_ship_this_round
|
||||
skip_condition: "all_null"
|
||||
|
||||
- name: "Game Over"
|
||||
tokens_for_ai: |
|
||||
The naval battle has ended! Generate an epic conclusion.
|
||||
|
||||
Based on the metadata:
|
||||
- If user_wins is true: "🎉 TOTAL VICTORY! You have destroyed all enemy ships! The seas belong to you, Admiral. Your tactical brilliance has secured complete naval supremacy."
|
||||
- If ai_wins is true: "💀 DEFEAT! All your ships have been destroyed. Your fleet lies scattered across the ocean floor. The enemy's superior strategy has prevailed."
|
||||
|
||||
Make it dramatic and final - this is the end of the battle!
|
||||
metadata_filter:
|
||||
- game_over
|
||||
- user_wins
|
||||
- ai_wins
|
||||
skip_condition: "all_false"
|
||||
|
||||
processing_script: |
|
||||
import random
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
import io
|
||||
import base64
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Define ship sizes
|
||||
ship_sizes = {
|
||||
"Carrier": 5,
|
||||
"Battleship": 4,
|
||||
"Cruiser": 3,
|
||||
"Submarine": 3,
|
||||
"Destroyer": 2
|
||||
}
|
||||
|
||||
# Define colors for ships
|
||||
ship_colors = {
|
||||
"Carrier": "blue",
|
||||
"Battleship": "green",
|
||||
"Cruiser": "orange",
|
||||
"Submarine": "purple",
|
||||
"Destroyer": "pink"
|
||||
}
|
||||
|
||||
# Retrieve the game state
|
||||
user_board = metadata.get("user_board")
|
||||
ai_board = metadata.get("ai_board")
|
||||
|
||||
# Normal processing code
|
||||
user_shots = metadata.get("user_shots", [])
|
||||
ai_shots = metadata.get("ai_shots", [])
|
||||
user_hits = metadata.get("user_hits", [])
|
||||
ai_hits = metadata.get("ai_hits", [])
|
||||
game_over = metadata.get("game_over", False)
|
||||
user_wins = False
|
||||
ai_wins = False
|
||||
user_hit_result = "miss"
|
||||
ai_hit_result = "miss"
|
||||
user_sunk_ships = metadata.get("user_sunk_ships", [])
|
||||
ai_sunk_ships = metadata.get("ai_sunk_ships", [])
|
||||
user_sunk_ship_this_round = None
|
||||
ai_sunk_ship_this_round = None
|
||||
|
||||
# AI state variables
|
||||
ai_mode = metadata.get("ai_mode", "random")
|
||||
|
||||
# Initialize probability matrix with realistic ship placement probabilities
|
||||
if "probability_matrix" not in metadata:
|
||||
probability_matrix = [[0] * 10 for _ in range(10)]
|
||||
# Calculate how many ship placements use each cell
|
||||
ship_lengths = [5, 4, 3, 3, 2]
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
count = 0
|
||||
for ship_len in ship_lengths:
|
||||
# Horizontal ships that would cover this cell
|
||||
for start_x in range(max(0, x - ship_len + 1), min(x + 1, 10 - ship_len + 1)):
|
||||
count += 1
|
||||
# Vertical ships that would cover this cell
|
||||
for start_y in range(max(0, y - ship_len + 1), min(y + 1, 10 - ship_len + 1)):
|
||||
count += 1
|
||||
probability_matrix[y][x] = count
|
||||
# print("DEBUG: Initial probability matrix created")
|
||||
# Debug print the initial grid
|
||||
# print("DEBUG: Initial grid:")
|
||||
# for row in probability_matrix:
|
||||
# print(f" {' '.join(f'{x:2d}' for x in row)}")
|
||||
else:
|
||||
probability_matrix = metadata.get("probability_matrix")
|
||||
# print("DEBUG: Using existing probability matrix")
|
||||
hits = metadata.get("hits", [])
|
||||
misses = metadata.get("misses", [])
|
||||
sunk_ships = metadata.get("sunk_ships", [])
|
||||
|
||||
# Function to check if a ship is sunk
|
||||
def check_sunk(board, hits, ship_name):
|
||||
ship_positions = []
|
||||
for i, ship in enumerate(board):
|
||||
if ship == ship_name:
|
||||
ship_positions.append(i)
|
||||
for pos in ship_positions:
|
||||
if pos not in hits:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Function to draw a line across a sunken ship
|
||||
def draw_line(ax, board, ship_name):
|
||||
ship_positions = []
|
||||
for i, ship in enumerate(board):
|
||||
if ship == ship_name:
|
||||
ship_positions.append(i)
|
||||
if not ship_positions:
|
||||
return
|
||||
|
||||
# Determine if the ship is horizontal or vertical
|
||||
first_pos = ship_positions[0]
|
||||
last_pos = ship_positions[-1]
|
||||
if last_pos - first_pos < 10: # Horizontal
|
||||
x_start, y_start = first_pos % 10 + 0.5, 9 - first_pos // 10 + 0.5
|
||||
x_end, y_end = last_pos % 10 + 0.5, 9 - last_pos // 10 + 0.5
|
||||
else: # Vertical
|
||||
x_start, y_start = first_pos % 10 + 0.5, 9 - first_pos // 10 + 0.5
|
||||
x_end, y_end = first_pos % 10 + 0.5, 9 - last_pos // 10 + 0.5
|
||||
|
||||
ax.plot([x_start, x_end], [y_start, y_end], color='red', linewidth=2)
|
||||
|
||||
# Function to update probability matrix
|
||||
def update_probability(x, y, hit):
|
||||
global probability_matrix, hits, misses, sunk_ships, ship_sizes
|
||||
|
||||
if hit:
|
||||
hits.append((x, y))
|
||||
probability_matrix[y][x] = 0 # Mark hit
|
||||
# Increase probabilities for adjacent cells
|
||||
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
|
||||
nx, ny = x + dx, y + dy
|
||||
if 0 <= nx < 10 and 0 <= ny < 10 and probability_matrix[ny][nx] > 0:
|
||||
probability_matrix[ny][nx] += 5 # Increase probability significantly
|
||||
else:
|
||||
misses.append((x, y))
|
||||
probability_matrix[y][x] = -1 # Mark miss
|
||||
|
||||
# Set probabilities to 1 for cells that can't fit any remaining ships
|
||||
max_ship_size = max(size for ship, size in ship_sizes.items() if ship not in sunk_ships)
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
if probability_matrix[y][x] > 0 and not can_fit_ship(x, y, max_ship_size):
|
||||
probability_matrix[y][x] = 1 # Minimum probability
|
||||
|
||||
# Function to check if a ship can fit
|
||||
def can_fit_ship(x, y, ship_size):
|
||||
# Check horizontal fit
|
||||
if x + ship_size <= 10:
|
||||
fit = True
|
||||
for i in range(ship_size):
|
||||
if probability_matrix[y][x+i] <= 0:
|
||||
fit = False
|
||||
break
|
||||
if fit:
|
||||
return True
|
||||
# Check vertical fit
|
||||
if y + ship_size <= 10:
|
||||
fit = True
|
||||
for i in range(ship_size):
|
||||
if probability_matrix[y+i][x] <= 0:
|
||||
fit = False
|
||||
break
|
||||
if fit:
|
||||
return True
|
||||
return False
|
||||
|
||||
# Function to generate Hermes reasoning
|
||||
def hermes_reason_move(game_state, turn_number, top_candidates):
|
||||
global ai_hits, ai_shots, ai_sunk_ships, probability_matrix
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Get Hermes endpoint from environment
|
||||
hermes_endpoint = os.environ.get('MODEL_ENDPOINT_1', 'https://hermes.ai.unturf.com/v1')
|
||||
hermes_api_key = os.environ.get('MODEL_API_KEY_1', '')
|
||||
|
||||
# Prepare game state summary
|
||||
hits_summary = f"AI hits so far: {len(ai_hits)} positions hit"
|
||||
misses_summary = f"AI misses so far: {len(ai_shots) - len(ai_hits)} positions missed"
|
||||
sunk_ships_summary = f"Ships sunk: {len(ai_sunk_ships)} out of 5"
|
||||
available_positions = [i for i in range(100) if i not in ai_shots]
|
||||
top_six_candidates = top_candidates[0:6] if len(top_candidates) >= 6 else top_candidates
|
||||
|
||||
# Create reasoning prompt
|
||||
prompt = (
|
||||
f"You are an expert Battleship AI. Turn {turn_number}.\n\n"
|
||||
f"CRITICAL: You MUST choose from these TOP probability positions: {top_six_candidates}\n\n"
|
||||
f"Game Data:\n"
|
||||
f"- {hits_summary}\n"
|
||||
f"- {misses_summary}\n"
|
||||
f"- {sunk_ships_summary}\n\n"
|
||||
f"INSTRUCTIONS: Pick ONE number from {top_six_candidates} - these are the mathematically optimal targets.\n\n"
|
||||
f"Format your response EXACTLY like this:\n\n"
|
||||
f"ANALYSIS: [3 sentences explaining why you chose from the top probability positions]\n\n"
|
||||
f"MOVE: [ONE number from this list: {top_six_candidates}]\n\n"
|
||||
f"You MUST pick from {top_six_candidates} - do not pick any other number."
|
||||
)
|
||||
|
||||
try:
|
||||
headers = {
|
||||
'Authorization': f'Bearer {hermes_api_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
data = {
|
||||
'model': 'adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic',
|
||||
'messages': [{'role': 'user', 'content': prompt}],
|
||||
'max_tokens': 300,
|
||||
'temperature': 0.5
|
||||
}
|
||||
|
||||
response = requests.post(f'{hermes_endpoint}/chat/completions',
|
||||
headers=headers, json=data, timeout=10)
|
||||
|
||||
# print(f"DEBUG: API Status: {response.status_code}")
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
reasoning = result['choices'][0]['message']['content'].strip()
|
||||
# print(f"DEBUG: Real API response: {reasoning}")
|
||||
return reasoning
|
||||
else:
|
||||
# print(f"DEBUG: API failed with status {response.status_code}: {response.text[:200]}")
|
||||
fallback_move = top_candidates[0] if top_candidates else random.choice([i for i in range(100) if i not in ai_shots])
|
||||
return f"ANALYSIS: Turn {turn_number} suggests targeting high-probability zones based on mathematical analysis. The current hit pattern indicates potential ship orientations that guide strategic decisions. Focusing on adjacent unexplored cells maximizes discovery potential.\n\nMOVE: {fallback_move}"
|
||||
|
||||
except Exception as e:
|
||||
# print(f"DEBUG: API exception: {str(e)}")
|
||||
fallback_move = top_candidates[0] if top_candidates else random.choice([i for i in range(100) if i not in ai_shots])
|
||||
return f"ANALYSIS: After {turn_number} turns, probability analysis guides optimal targeting strategies. Current data suggests focusing on clustered high-value positions for maximum efficiency. Strategic patience combined with mathematical precision will yield victory.\n\nMOVE: {fallback_move}"
|
||||
|
||||
# AI chooses a shot
|
||||
def choose_ai_shot():
|
||||
global can_fit_ship, update_probability, generate_hunt_targets, random_search, probability_matrix, ai_mode, ai_shots, random, user_board, ai_hits, ai_hit_result, hermes_reason_move, ship_sizes, ai_sunk_ships
|
||||
|
||||
if ai_mode == "hermes_reasoner":
|
||||
# Use probability algorithm + Hermes reasoning
|
||||
|
||||
# Update probability matrix based on shots
|
||||
remaining_ships = [ship for ship in ship_sizes.keys() if ship not in ai_sunk_ships]
|
||||
remaining_ship_sizes = [ship_sizes[ship] for ship in remaining_ships]
|
||||
# print(f"DEBUG: Remaining ships: {remaining_ships}")
|
||||
# print(f"DEBUG: Total shots: {len(ai_shots)}, Hits: {len(ai_hits)}, Misses: {len(ai_shots) - len(ai_hits)}")
|
||||
|
||||
# Recalculate entire probability matrix
|
||||
new_probability_matrix = [[0] * 10 for _ in range(10)]
|
||||
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
pos = y * 10 + x
|
||||
if pos in ai_shots:
|
||||
new_probability_matrix[y][x] = 0 # Already shot
|
||||
else:
|
||||
# Count how many ship placements could use this cell
|
||||
for ship_size in remaining_ship_sizes:
|
||||
# Check horizontal placements
|
||||
for start_x in range(max(0, x - ship_size + 1), min(x + 1, 10 - ship_size + 1)):
|
||||
valid = True
|
||||
includes_hit = False
|
||||
for dx in range(ship_size):
|
||||
check_pos = y * 10 + (start_x + dx)
|
||||
if check_pos in ai_shots and check_pos not in ai_hits:
|
||||
valid = False # Ship can't go through a miss
|
||||
break
|
||||
if check_pos in ai_hits:
|
||||
includes_hit = True
|
||||
if valid:
|
||||
# Base probability for valid placement
|
||||
new_probability_matrix[y][x] += 1
|
||||
# Bonus if it includes a hit
|
||||
if includes_hit:
|
||||
new_probability_matrix[y][x] += 10
|
||||
|
||||
# Check vertical placements
|
||||
for start_y in range(max(0, y - ship_size + 1), min(y + 1, 10 - ship_size + 1)):
|
||||
valid = True
|
||||
includes_hit = False
|
||||
for dy in range(ship_size):
|
||||
check_pos = (start_y + dy) * 10 + x
|
||||
if check_pos in ai_shots and check_pos not in ai_hits:
|
||||
valid = False # Ship can't go through a miss
|
||||
break
|
||||
if check_pos in ai_hits:
|
||||
includes_hit = True
|
||||
if valid:
|
||||
# Base probability for valid placement
|
||||
new_probability_matrix[y][x] += 1
|
||||
# Bonus if it includes a hit
|
||||
if includes_hit:
|
||||
new_probability_matrix[y][x] += 10
|
||||
|
||||
# Replace the old matrix with the new one
|
||||
probability_matrix = new_probability_matrix
|
||||
|
||||
# Boost probabilities around unsunk hits
|
||||
for hit_pos in ai_hits:
|
||||
hit_x, hit_y = hit_pos % 10, hit_pos // 10
|
||||
# Check if this hit is part of a sunk ship
|
||||
hit_is_sunk = False
|
||||
for ship_name in ai_sunk_ships:
|
||||
# This would need ship position tracking to work properly
|
||||
pass # Skip for now, assume all hits need chasing
|
||||
|
||||
if not hit_is_sunk:
|
||||
# Boost adjacent cells
|
||||
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
|
||||
adj_x, adj_y = hit_x + dx, hit_y + dy
|
||||
if 0 <= adj_x < 10 and 0 <= adj_y < 10:
|
||||
adj_pos = adj_y * 10 + adj_x
|
||||
if adj_pos not in ai_shots:
|
||||
# Only boost if not already boosted
|
||||
if probability_matrix[adj_y][adj_x] < 50:
|
||||
probability_matrix[adj_y][adj_x] = 50 # Set to fixed high value instead of adding
|
||||
|
||||
# Find top 6 highest probability positions
|
||||
position_probs = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots: # Only consider unshot positions
|
||||
x, y = i % 10, i // 10
|
||||
position_probs.append((probability_matrix[y][x], i))
|
||||
|
||||
# Sort by probability (descending) and take top positions
|
||||
position_probs.sort(reverse=True)
|
||||
candidates = [pos for prob, pos in position_probs[:20]] # Take top 20 for variety
|
||||
max_prob = position_probs[0][0] if position_probs else 0
|
||||
|
||||
# Fallback if no candidates found
|
||||
if not candidates:
|
||||
candidates = [i for i in range(100) if i not in ai_shots]
|
||||
|
||||
# Debug: Log what we're working with
|
||||
turn_number = len(ai_shots) + 1
|
||||
# print(f"DEBUG: Turn {turn_number}, Max prob: {max_prob}")
|
||||
# print("DEBUG: Probability grid:")
|
||||
# for y in range(10):
|
||||
# row = [f"{probability_matrix[y][x]:2d}" for x in range(10)]
|
||||
# print(f" {' '.join(row)}")
|
||||
# print(f"DEBUG: Top candidates: {candidates[:10]}")
|
||||
|
||||
reasoning_response = hermes_reason_move("battleship", turn_number, candidates)
|
||||
|
||||
# Analysis already logged in hermes_reason_move function
|
||||
|
||||
# Extract move from response - try multiple parsing methods
|
||||
try:
|
||||
if "MOVE:" in reasoning_response:
|
||||
move_part = reasoning_response.split("MOVE:")[1].strip()
|
||||
ai_shot = int(move_part.split()[0])
|
||||
# print(f"DEBUG: Hermes Move: {ai_shot} (from 'MOVE: {move_part.split()[0]}')")
|
||||
else:
|
||||
# Fallback: extract any number from the response that's in candidates
|
||||
import re
|
||||
numbers = re.findall(r'\b(\d+)\b', reasoning_response)
|
||||
valid_moves = [int(n) for n in numbers if int(n) in candidates and int(n) not in ai_shots]
|
||||
if valid_moves:
|
||||
ai_shot = valid_moves[0]
|
||||
# print(f"DEBUG: Hermes Move (parsed): {ai_shot} from numbers {numbers}")
|
||||
else:
|
||||
raise Exception(f"ERROR: Hermes response had no valid moves! Response: {reasoning_response}, Candidates: {candidates}")
|
||||
|
||||
# Validate the shot is legal
|
||||
if ai_shot in ai_shots or ai_shot < 0 or ai_shot > 99:
|
||||
ai_shot = random.choice(candidates)
|
||||
# print(f"DEBUG: Invalid shot, using fallback: {ai_shot}")
|
||||
|
||||
except Exception as e:
|
||||
ai_shot = random.choice(candidates)
|
||||
# print(f"DEBUG: Parse error: {e}, using fallback: {ai_shot}")
|
||||
|
||||
elif ai_mode == "super_hunter":
|
||||
# Use probabilistic grid algorithm
|
||||
max_prob = 0
|
||||
candidates = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots: # Exclude already-fired cells
|
||||
x, y = i % 10, i // 10
|
||||
if probability_matrix[y][x] > max_prob:
|
||||
max_prob = probability_matrix[y][x]
|
||||
candidates = [i]
|
||||
elif probability_matrix[y][x] == max_prob:
|
||||
candidates.append(i)
|
||||
ai_shot = random.choice(candidates)
|
||||
elif ai_mode == "hunter":
|
||||
# Simple hunter mode logic
|
||||
if hits:
|
||||
# Target adjacent cells of the last hit
|
||||
last_hit = hits[-1]
|
||||
hunt_targets = generate_hunt_targets(last_hit, ai_shots)
|
||||
if hunt_targets:
|
||||
ai_shot = hunt_targets.pop(0)
|
||||
else:
|
||||
ai_shot = random_search()
|
||||
else:
|
||||
ai_shot = random_search()
|
||||
else:
|
||||
# Random mode
|
||||
ai_shot = random_search()
|
||||
|
||||
# Update AI state after the shot
|
||||
if user_board[ai_shot] != -1:
|
||||
ai_hits.append(ai_shot)
|
||||
ai_hit_result = "hit"
|
||||
if ai_mode == "super_hunter" or ai_mode == "hermes_reasoner":
|
||||
update_probability(ai_shot % 10, ai_shot // 10, True)
|
||||
else:
|
||||
ai_hit_result = "miss"
|
||||
if ai_mode == "super_hunter" or ai_mode == "hermes_reasoner":
|
||||
update_probability(ai_shot % 10, ai_shot // 10, False)
|
||||
|
||||
return ai_shot
|
||||
|
||||
# Function for random search
|
||||
def random_search():
|
||||
available_positions = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots:
|
||||
available_positions.append(i)
|
||||
return random.choice(available_positions)
|
||||
|
||||
# Function to generate hunt targets around a hit
|
||||
def generate_hunt_targets(hit_position, ai_shots):
|
||||
potential_targets = []
|
||||
row, col = divmod(hit_position, 10)
|
||||
|
||||
# Up
|
||||
if row > 0:
|
||||
potential_targets.append(hit_position - 10)
|
||||
# Down
|
||||
if row < 9:
|
||||
potential_targets.append(hit_position + 10)
|
||||
# Left
|
||||
if col > 0:
|
||||
potential_targets.append(hit_position - 1)
|
||||
# Right
|
||||
if col < 9:
|
||||
potential_targets.append(hit_position + 1)
|
||||
|
||||
# Filter out already fired positions
|
||||
filtered_targets = []
|
||||
for pos in potential_targets:
|
||||
if pos not in ai_shots:
|
||||
filtered_targets.append(pos)
|
||||
return filtered_targets
|
||||
|
||||
# Get the user's shot
|
||||
try:
|
||||
user_shot = int(metadata.get("user_shot"))
|
||||
except (IndexError, ValueError) as e:
|
||||
user_shot = -1
|
||||
|
||||
if game_over:
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"game_over": True,
|
||||
"user_wins": user_wins,
|
||||
"ai_wins": ai_wins
|
||||
}
|
||||
}
|
||||
# print(f"DEBUG: Game over detected! User wins: {user_wins}, AI wins: {ai_wins}")
|
||||
elif 0 <= user_shot < 100 and user_shot not in user_shots:
|
||||
# The move is valid
|
||||
user_shots.append(user_shot)
|
||||
user_hit_result = "miss"
|
||||
if ai_board[user_shot] != -1:
|
||||
user_hits.append(user_shot)
|
||||
user_hit_result = "hit"
|
||||
|
||||
# AI makes a move
|
||||
ai_shot = choose_ai_shot()
|
||||
ai_shots.append(ai_shot)
|
||||
|
||||
# Check if any AI ship is sunk
|
||||
for ship_name in ship_sizes.keys():
|
||||
if check_sunk(ai_board, user_hits, ship_name) and ship_name not in user_sunk_ships:
|
||||
user_sunk_ships.append(ship_name)
|
||||
user_sunk_ship_this_round = ship_name
|
||||
# print(f"DEBUG: USER SUNK AI SHIP: {ship_name}")
|
||||
|
||||
# Check if any User ship is sunk
|
||||
for ship_name in ship_sizes.keys():
|
||||
if check_sunk(user_board, ai_hits, ship_name) and ship_name not in ai_sunk_ships:
|
||||
ai_sunk_ships.append(ship_name)
|
||||
ai_sunk_ship_this_round = ship_name
|
||||
# print(f"DEBUG: AI SUNK USER SHIP: {ship_name}")
|
||||
|
||||
# Check if all AI ships are hit
|
||||
all_ai_ships_hit = True
|
||||
for pos in range(100):
|
||||
if ai_board[pos] != -1 and pos not in user_hits:
|
||||
all_ai_ships_hit = False
|
||||
break
|
||||
|
||||
# Check if all User ships are hit
|
||||
all_user_ships_hit = True
|
||||
for pos in range(100):
|
||||
if user_board[pos] != -1 and pos not in ai_hits:
|
||||
all_user_ships_hit = False
|
||||
break
|
||||
|
||||
if all_ai_ships_hit:
|
||||
game_over = True
|
||||
user_wins = True
|
||||
ai_wins = False
|
||||
# print(f"DEBUG: USER WINS! All AI ships destroyed. Game over.")
|
||||
elif all_user_ships_hit:
|
||||
game_over = True
|
||||
user_wins = False
|
||||
ai_wins = True
|
||||
# print(f"DEBUG: AI WINS! All user ships destroyed. Game over.")
|
||||
|
||||
# Only track winning move if there's exactly 1 position left (for next turn's categorization)
|
||||
user_winning_move = None
|
||||
ai_winning_move = None
|
||||
|
||||
# Check which user move would win the game (AI ship positions left)
|
||||
ai_ship_positions_left = [pos for pos in range(100) if ai_board[pos] != -1 and pos not in user_hits]
|
||||
if len(ai_ship_positions_left) == 1:
|
||||
user_winning_move = ai_ship_positions_left[0]
|
||||
# print(f"DEBUG: User has exactly 1 winning move at position {user_winning_move}")
|
||||
else:
|
||||
# print(f"DEBUG: User has {len(ai_ship_positions_left)} AI positions left - no winning move")
|
||||
pass
|
||||
|
||||
# Check which AI move would win the game (user ship positions left)
|
||||
user_ship_positions_left = [pos for pos in range(100) if user_board[pos] != -1 and pos not in ai_hits]
|
||||
if len(user_ship_positions_left) == 1:
|
||||
ai_winning_move = user_ship_positions_left[0]
|
||||
# print(f"DEBUG: AI has exactly 1 winning move at position {ai_winning_move}")
|
||||
else:
|
||||
# print(f"DEBUG: AI has {len(user_ship_positions_left)} user positions left - no winning move")
|
||||
pass
|
||||
|
||||
# Plot the boards
|
||||
fig, axs = plt.subplots(1, 2, figsize=(12, 6))
|
||||
fig.suptitle("Battleship", fontsize=16)
|
||||
|
||||
# User's view of AI's board
|
||||
axs[0].set_xlim(0, 10)
|
||||
axs[0].set_ylim(0, 10)
|
||||
axs[0].set_xticks([])
|
||||
axs[0].set_yticks([])
|
||||
axs[0].grid(True)
|
||||
axs[0].set_title("Your Shots", fontsize=12)
|
||||
|
||||
# Plot user shots on AI's board
|
||||
for i in range(100):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if i in user_shots:
|
||||
if i in user_hits:
|
||||
axs[0].text(x + 0.5, y + 0.5, 'X', fontsize=12, ha='center', va='center', color='red')
|
||||
else:
|
||||
axs[0].text(x + 0.5, y + 0.5, 'O', fontsize=12, ha='center', va='center', color='black')
|
||||
axs[0].text(x + 0.5, y + 0.5, str(i), fontsize=8, ha='center', va='center', color='gray')
|
||||
|
||||
# AI's view of User's board
|
||||
axs[1].set_xlim(0, 10)
|
||||
axs[1].set_ylim(0, 10)
|
||||
axs[1].set_xticks([])
|
||||
axs[1].set_yticks([])
|
||||
axs[1].grid(True)
|
||||
axs[1].set_title("Your Ships", fontsize=12)
|
||||
|
||||
# Plot user ships
|
||||
for i, ship in enumerate(user_board):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if ship != -1:
|
||||
axs[1].add_patch(plt.Rectangle((x, y), 1, 1, color=ship_colors[ship], alpha=0.5))
|
||||
|
||||
# Plot AI shots on User's board
|
||||
for i in range(100):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if i in ai_shots:
|
||||
if i in ai_hits:
|
||||
axs[1].text(x + 0.5, y + 0.5, 'X', fontsize=12, ha='center', va='center', color='red')
|
||||
else:
|
||||
axs[1].text(x + 0.5, y + 0.5, 'O', fontsize=12, ha='center', va='center', color='black')
|
||||
axs[1].text(x + 0.5, y + 0.5, str(i), fontsize=8, ha='center', va='center', color='gray')
|
||||
|
||||
# Draw lines across sunk ships
|
||||
for ship_name in user_sunk_ships:
|
||||
draw_line(axs[0], ai_board, ship_name)
|
||||
|
||||
for ship_name in ai_sunk_ships:
|
||||
draw_line(axs[1], user_board, ship_name)
|
||||
|
||||
# Add legend
|
||||
handles = []
|
||||
for color in ship_colors.values():
|
||||
handles.append(plt.Rectangle((0, 0), 1, 1, color=color, alpha=0.5))
|
||||
axs[1].legend(handles, ship_colors.keys(), loc='upper right', fontsize=8)
|
||||
|
||||
buf = io.BytesIO()
|
||||
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.1)
|
||||
plt.close(fig)
|
||||
buf.seek(0)
|
||||
plot_image = base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
# gpt-4: If "plot_image" is in the result, set it as the background image
|
||||
# print(f"DEBUG: Setting metadata for feedback - user_sunk_ship_this_round: {user_sunk_ship_this_round}, ai_sunk_ship_this_round: {ai_sunk_ship_this_round}")
|
||||
|
||||
script_result = {
|
||||
"plot_image": plot_image,
|
||||
"set_background": True,
|
||||
"metadata": {
|
||||
"user_board": user_board,
|
||||
"ai_board": ai_board,
|
||||
"user_shot": user_shot,
|
||||
"ai_shot": ai_shot,
|
||||
"user_shots": user_shots,
|
||||
"ai_shots": ai_shots,
|
||||
"user_hits": user_hits,
|
||||
"ai_hits": ai_hits,
|
||||
"game_over": game_over,
|
||||
"user_wins": user_wins,
|
||||
"ai_wins": ai_wins,
|
||||
"user_hit_result": user_hit_result,
|
||||
"ai_hit_result": ai_hit_result,
|
||||
"user_sunk_ships": user_sunk_ships,
|
||||
"ai_sunk_ships": ai_sunk_ships,
|
||||
"user_sunk_ship_this_round": user_sunk_ship_this_round,
|
||||
"ai_sunk_ship_this_round": ai_sunk_ship_this_round,
|
||||
"ai_mode": ai_mode,
|
||||
"probability_matrix": probability_matrix,
|
||||
"hits": hits,
|
||||
"misses": misses,
|
||||
"sunk_ships": sunk_ships,
|
||||
"user_winning_move": user_winning_move,
|
||||
"ai_winning_move": ai_winning_move
|
||||
}
|
||||
}
|
||||
|
||||
# Check if this was a winning move and override transition
|
||||
if game_over:
|
||||
script_result["next_section_and_step"] = "section_1:step_3"
|
||||
# print(f"POST-SCRIPT: Game over detected, overriding transition to step_3")
|
||||
else:
|
||||
script_result = {
|
||||
"error": f"Invalid shot: {metadata.get('user_shot')}",
|
||||
"metadata": {}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- valid_move
|
||||
- invalid_move
|
||||
- exit
|
||||
- restart
|
||||
transitions:
|
||||
valid_move:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
The user shot seems valid.
|
||||
metadata_tmp_add:
|
||||
user_shot: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
invalid_move:
|
||||
content_blocks:
|
||||
- "That move is invalid. Please choose a position between 0 and 99."
|
||||
metadata_tmp_add:
|
||||
user_shot: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_4"
|
||||
restart:
|
||||
content_blocks:
|
||||
- "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Game Over"
|
||||
question: "Would you like to restart and play again, or would you prefer to exit?"
|
||||
tokens_for_ai: |
|
||||
If the user wants to restart or play again, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
buckets:
|
||||
- restart
|
||||
- exit
|
||||
transitions:
|
||||
restart:
|
||||
content_blocks:
|
||||
- "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
exit:
|
||||
content_blocks:
|
||||
- "Thank you for playing Battleship! 🎉"
|
||||
- "Feel free to come back anytime for another game."
|
||||
next_section_and_step: "section_1:step_4"
|
||||
|
||||
- step_id: "step_4"
|
||||
title: "Goodbye"
|
||||
content_blocks:
|
||||
- "Thanks for playing! Hope you enjoyed the battle at sea."
|
||||
|
|
@ -1,892 +0,0 @@
|
|||
default_max_attempts_per_step: 9
|
||||
tokens_for_ai_rubric: |
|
||||
based on the game without knowing where each ship was, score the process each player used to target ships.
|
||||
|
||||
be sure to look for moves or strategies in the game play that where _not_ smart given the obvious information uncovered.
|
||||
|
||||
use chain-of-thought to reason about the progression of the game and the winner.
|
||||
|
||||
first summarize the game, we don't need the turn by turn plays.
|
||||
|
||||
the game was battleship. the moves were done 1 by 1.
|
||||
the grid is 0-99.
|
||||
|
||||
did any player blunder as the information was learned?
|
||||
|
||||
There was a user and an AI playing.
|
||||
|
||||
Depending on the game mode the player chooses they are going up against a different algo,
|
||||
|
||||
* random
|
||||
|
||||
* always plays randomly
|
||||
|
||||
* hunter
|
||||
|
||||
* keeps track of hits and targets every cell around it no matter what, randomly, else random
|
||||
|
||||
* super human hunter
|
||||
|
||||
* keeps track of hits and uses a probability grid normalized to 100 and always picks the max or random of any 100.
|
||||
|
||||
* hermes reasoner
|
||||
|
||||
* uses the probability algorithm paired with hermes to reason for 3 sentences about what the next 0-99 move should be given the current game state and turn number
|
||||
|
||||
Did any player miss sinking a ship that was found? was it due to end game or a blunder?
|
||||
|
||||
Do not mix up ships, keep careful track of the order they were found and sunk.
|
||||
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Battleship"
|
||||
steps:
|
||||
- step_id: "step_0"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- |
|
||||
Welcome to Battleship! 🚢
|
||||
In this game, both you and the AI have a fleet of ships placed randomly on a 10x10 grid.
|
||||
The grid positions are numbered 0 to 99.
|
||||
|
||||
Your goal is to sink all of the AI's ships before it sinks yours.
|
||||
Let's get started!
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Choose AI Mode"
|
||||
question: "Choose the AI mode: Random, Hunter, Super Human Hunter, or Hermes Reasoner?"
|
||||
tokens_for_ai: |
|
||||
If the user chooses Random, categorize as 'random_mode'.
|
||||
If the user chooses Hunter, categorize as 'hunter_mode'.
|
||||
If the user chooses Super Human Hunter, categorize as 'super_hunter_mode'.
|
||||
If the user chooses Hermes Reasoner, categorize as 'hermes_reasoner_mode'.
|
||||
feedback_tokens_for_ai: |
|
||||
If the user chooses Random, say: "Random mode selected! The AI will make completely random moves."
|
||||
If the user chooses Hunter, say: "Hunter mode selected! The AI will systematically hunt around hits."
|
||||
If the user chooses Super Human Hunter, say: "Super Human Hunter mode selected! The AI will use advanced probability analysis."
|
||||
If the user chooses Hermes Reasoner, say: "Hermes Reasoner mode selected! The AI will use probability analysis combined with reasoning to make strategic decisions."
|
||||
processing_script: |
|
||||
import random
|
||||
|
||||
def place_ships():
|
||||
global random
|
||||
# Define ship sizes and names
|
||||
ships = {
|
||||
"Testship": 1
|
||||
}
|
||||
|
||||
board = [-1] * 100
|
||||
# Place testship at position 21 for easy testing
|
||||
board[21] = "Testship"
|
||||
return board
|
||||
|
||||
user_board = place_ships()
|
||||
ai_board = place_ships() # AI also gets randomly placed ships
|
||||
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"user_board": user_board,
|
||||
"ai_board": ai_board
|
||||
}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- random_mode
|
||||
- hunter_mode
|
||||
- super_hunter_mode
|
||||
- hermes_reasoner_mode
|
||||
transitions:
|
||||
random_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Random Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "random"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
hunter_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Hunter Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "hunter"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
super_hunter_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Super Human Hunter Mode enabled for the AI."
|
||||
metadata_add:
|
||||
ai_mode: "super_hunter"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
hermes_reasoner_mode:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Hermes Reasoner Mode enabled for the AI. The AI will use probability analysis combined with reasoning to make strategic decisions."
|
||||
metadata_add:
|
||||
ai_mode: "hermes_reasoner"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Take a Shot"
|
||||
question: "Choose a position to fire at (0-99)."
|
||||
pre_script: |
|
||||
# Check if moves match winning moves from previous turn
|
||||
user_winning_move = metadata.get("user_winning_move")
|
||||
ai_winning_move = metadata.get("ai_winning_move")
|
||||
user_shot_input = metadata.get("user_response", "")
|
||||
print(f"PRE-SCRIPT DEBUG: user_shot_input = '{user_shot_input}', user_winning_move = {user_winning_move}, ai_winning_move = {ai_winning_move}")
|
||||
ai_shot = metadata.get("ai_shot")
|
||||
|
||||
is_game_ending_move = False
|
||||
|
||||
# Check if user move wins
|
||||
if user_shot_input and user_shot_input.isdigit():
|
||||
user_move = int(user_shot_input)
|
||||
if user_winning_move is not None and user_move == user_winning_move:
|
||||
is_game_ending_move = True
|
||||
print(f"PRE-SCRIPT: User winning move detected! user_move={user_move} matches user_winning_move={user_winning_move}")
|
||||
|
||||
# Check if AI move wins (from previous turn)
|
||||
if ai_shot is not None and ai_winning_move is not None and ai_shot == ai_winning_move:
|
||||
is_game_ending_move = True
|
||||
print(f"PRE-SCRIPT: AI winning move detected! ai_shot={ai_shot} matches ai_winning_move={ai_winning_move}")
|
||||
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"is_game_ending_move": is_game_ending_move
|
||||
}
|
||||
}
|
||||
tokens_for_ai: |
|
||||
1) If the user reply is *only* digits, and corresponds to a grid cell (0–99),
|
||||
treat it as a valid move:
|
||||
If the response matches the regex /^\d+$/ and 0 ≤ int(response) < 100, categorize as 'valid_move'.
|
||||
|
||||
2) Otherwise fall back to the usual buckets:
|
||||
If the user wants to restart or play again, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
Otherwise, categorize as 'invalid_move'.
|
||||
feedback_tokens_for_ai: |
|
||||
You are a battleship narrator. Each prompt has its own specific role - follow the individual prompt instructions precisely.
|
||||
feedback_prompts:
|
||||
- name: "Shot Report"
|
||||
tokens_for_ai: |
|
||||
🎯 Report ONLY the hit/miss results for both shots this turn. DO NOT report ship sinking or game over.
|
||||
|
||||
Check metadata:
|
||||
- user_shot: Player's target position
|
||||
- user_hit_result: "hit" or "miss"
|
||||
- ai_shot: AI's target position
|
||||
- ai_hit_result: "hit" or "miss"
|
||||
|
||||
Format: "🎯 Your shot at position [user_shot]: [user_hit_result]! 🤖 Enemy shot at position [ai_shot]: [ai_hit_result]!"
|
||||
metadata_filter:
|
||||
- user_shot
|
||||
- ai_shot
|
||||
- user_hit_result
|
||||
- ai_hit_result
|
||||
- user_response
|
||||
|
||||
- name: "Ship Status"
|
||||
tokens_for_ai: |
|
||||
A ship has been destroyed! Generate a dramatic 2-3 sentence description.
|
||||
|
||||
Metadata tells you which ship(s) were sunk:
|
||||
- user_sunk_ship_this_round: The ship YOU destroyed (your victory)
|
||||
- ai_sunk_ship_this_round: The ship that was destroyed by the enemy (your loss)
|
||||
|
||||
Format:
|
||||
- If user destroyed a ship: "💥 You've sunk their [ship]! [2-3 dramatic sentences imagining how this warship meets its doom]"
|
||||
- If AI destroyed your ship: "🔥 Your [ship] has been destroyed! [2-3 dramatic sentences about its destruction]"
|
||||
- If both: Include both messages
|
||||
metadata_filter:
|
||||
- user_sunk_ship_this_round
|
||||
- ai_sunk_ship_this_round
|
||||
skip_condition: "all_null"
|
||||
|
||||
- name: "Game Over"
|
||||
tokens_for_ai: |
|
||||
The naval battle has ended! Generate an epic conclusion.
|
||||
|
||||
Based on the metadata:
|
||||
- If user_wins is true: "🎉 TOTAL VICTORY! You have destroyed all enemy ships! The seas belong to you, Admiral. Your tactical brilliance has secured complete naval supremacy."
|
||||
- If ai_wins is true: "💀 DEFEAT! All your ships have been destroyed. Your fleet lies scattered across the ocean floor. The enemy's superior strategy has prevailed."
|
||||
|
||||
Make it dramatic and final - this is the end of the battle!
|
||||
metadata_filter:
|
||||
- game_over
|
||||
- user_wins
|
||||
- ai_wins
|
||||
skip_condition: "all_false"
|
||||
|
||||
processing_script: |
|
||||
import random
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
import io
|
||||
import base64
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Define ship sizes
|
||||
ship_sizes = {
|
||||
"Testship": 1
|
||||
}
|
||||
|
||||
# Define colors for ships
|
||||
ship_colors = {
|
||||
"Testship": "red"
|
||||
}
|
||||
|
||||
# Retrieve the game state
|
||||
user_board = metadata.get("user_board")
|
||||
ai_board = metadata.get("ai_board")
|
||||
|
||||
# Normal processing code
|
||||
user_shots = metadata.get("user_shots", [])
|
||||
ai_shots = metadata.get("ai_shots", [])
|
||||
user_hits = metadata.get("user_hits", [])
|
||||
ai_hits = metadata.get("ai_hits", [])
|
||||
game_over = metadata.get("game_over", False)
|
||||
user_wins = False
|
||||
ai_wins = False
|
||||
user_hit_result = "miss"
|
||||
ai_hit_result = "miss"
|
||||
user_sunk_ships = metadata.get("user_sunk_ships", [])
|
||||
ai_sunk_ships = metadata.get("ai_sunk_ships", [])
|
||||
user_sunk_ship_this_round = None
|
||||
ai_sunk_ship_this_round = None
|
||||
|
||||
# AI state variables
|
||||
ai_mode = metadata.get("ai_mode", "random")
|
||||
|
||||
# Initialize probability matrix with realistic ship placement probabilities
|
||||
if "probability_matrix" not in metadata:
|
||||
probability_matrix = [[0] * 10 for _ in range(10)]
|
||||
# Calculate how many ship placements use each cell
|
||||
ship_lengths = [5, 4, 3, 3, 2]
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
count = 0
|
||||
for ship_len in ship_lengths:
|
||||
# Horizontal ships that would cover this cell
|
||||
for start_x in range(max(0, x - ship_len + 1), min(x + 1, 10 - ship_len + 1)):
|
||||
count += 1
|
||||
# Vertical ships that would cover this cell
|
||||
for start_y in range(max(0, y - ship_len + 1), min(y + 1, 10 - ship_len + 1)):
|
||||
count += 1
|
||||
probability_matrix[y][x] = count
|
||||
print("DEBUG: Initial probability matrix created")
|
||||
# Debug print the initial grid
|
||||
print("DEBUG: Initial grid:")
|
||||
for row in probability_matrix:
|
||||
print(f" {' '.join(f'{x:2d}' for x in row)}")
|
||||
else:
|
||||
probability_matrix = metadata.get("probability_matrix")
|
||||
print("DEBUG: Using existing probability matrix")
|
||||
hits = metadata.get("hits", [])
|
||||
misses = metadata.get("misses", [])
|
||||
sunk_ships = metadata.get("sunk_ships", [])
|
||||
|
||||
# Function to check if a ship is sunk
|
||||
def check_sunk(board, hits, ship_name):
|
||||
ship_positions = []
|
||||
for i, ship in enumerate(board):
|
||||
if ship == ship_name:
|
||||
ship_positions.append(i)
|
||||
for pos in ship_positions:
|
||||
if pos not in hits:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Function to draw a line across a sunken ship
|
||||
def draw_line(ax, board, ship_name):
|
||||
ship_positions = []
|
||||
for i, ship in enumerate(board):
|
||||
if ship == ship_name:
|
||||
ship_positions.append(i)
|
||||
if not ship_positions:
|
||||
return
|
||||
|
||||
# Determine if the ship is horizontal or vertical
|
||||
first_pos = ship_positions[0]
|
||||
last_pos = ship_positions[-1]
|
||||
if last_pos - first_pos < 10: # Horizontal
|
||||
x_start, y_start = first_pos % 10 + 0.5, 9 - first_pos // 10 + 0.5
|
||||
x_end, y_end = last_pos % 10 + 0.5, 9 - last_pos // 10 + 0.5
|
||||
else: # Vertical
|
||||
x_start, y_start = first_pos % 10 + 0.5, 9 - first_pos // 10 + 0.5
|
||||
x_end, y_end = first_pos % 10 + 0.5, 9 - last_pos // 10 + 0.5
|
||||
|
||||
ax.plot([x_start, x_end], [y_start, y_end], color='red', linewidth=2)
|
||||
|
||||
# Function to update probability matrix
|
||||
def update_probability(x, y, hit):
|
||||
global probability_matrix, hits, misses, sunk_ships, ship_sizes
|
||||
|
||||
if hit:
|
||||
hits.append((x, y))
|
||||
probability_matrix[y][x] = 0 # Mark hit
|
||||
# Increase probabilities for adjacent cells
|
||||
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
|
||||
nx, ny = x + dx, y + dy
|
||||
if 0 <= nx < 10 and 0 <= ny < 10 and probability_matrix[ny][nx] > 0:
|
||||
probability_matrix[ny][nx] += 5 # Increase probability significantly
|
||||
else:
|
||||
misses.append((x, y))
|
||||
probability_matrix[y][x] = -1 # Mark miss
|
||||
|
||||
# Set probabilities to 1 for cells that can't fit any remaining ships
|
||||
max_ship_size = max(size for ship, size in ship_sizes.items() if ship not in sunk_ships)
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
if probability_matrix[y][x] > 0 and not can_fit_ship(x, y, max_ship_size):
|
||||
probability_matrix[y][x] = 1 # Minimum probability
|
||||
|
||||
# Function to check if a ship can fit
|
||||
def can_fit_ship(x, y, ship_size):
|
||||
# Check horizontal fit
|
||||
if x + ship_size <= 10:
|
||||
fit = True
|
||||
for i in range(ship_size):
|
||||
if probability_matrix[y][x+i] <= 0:
|
||||
fit = False
|
||||
break
|
||||
if fit:
|
||||
return True
|
||||
# Check vertical fit
|
||||
if y + ship_size <= 10:
|
||||
fit = True
|
||||
for i in range(ship_size):
|
||||
if probability_matrix[y+i][x] <= 0:
|
||||
fit = False
|
||||
break
|
||||
if fit:
|
||||
return True
|
||||
return False
|
||||
|
||||
# Function to generate Hermes reasoning
|
||||
def hermes_reason_move(game_state, turn_number, top_candidates):
|
||||
global ai_hits, ai_shots, ai_sunk_ships, probability_matrix
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Get Hermes endpoint from environment
|
||||
hermes_endpoint = os.environ.get('MODEL_ENDPOINT_1', 'https://hermes.ai.unturf.com/v1')
|
||||
hermes_api_key = os.environ.get('MODEL_API_KEY_1', '')
|
||||
|
||||
# Prepare game state summary
|
||||
hits_summary = f"AI hits so far: {len(ai_hits)} positions hit"
|
||||
misses_summary = f"AI misses so far: {len(ai_shots) - len(ai_hits)} positions missed"
|
||||
sunk_ships_summary = f"Ships sunk: {len(ai_sunk_ships)} out of 5"
|
||||
available_positions = [i for i in range(100) if i not in ai_shots]
|
||||
top_six_candidates = top_candidates[0:6] if len(top_candidates) >= 6 else top_candidates
|
||||
|
||||
# Create reasoning prompt
|
||||
prompt = (
|
||||
f"You are an expert Battleship AI. Turn {turn_number}.\n\n"
|
||||
f"CRITICAL: You MUST choose from these TOP probability positions: {top_six_candidates}\n\n"
|
||||
f"Game Data:\n"
|
||||
f"- {hits_summary}\n"
|
||||
f"- {misses_summary}\n"
|
||||
f"- {sunk_ships_summary}\n\n"
|
||||
f"INSTRUCTIONS: Pick ONE number from {top_six_candidates} - these are the mathematically optimal targets.\n\n"
|
||||
f"Format your response EXACTLY like this:\n\n"
|
||||
f"ANALYSIS: [3 sentences explaining why you chose from the top probability positions]\n\n"
|
||||
f"MOVE: [ONE number from this list: {top_six_candidates}]\n\n"
|
||||
f"You MUST pick from {top_six_candidates} - do not pick any other number."
|
||||
)
|
||||
|
||||
try:
|
||||
headers = {
|
||||
'Authorization': f'Bearer {hermes_api_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
data = {
|
||||
'model': 'adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic',
|
||||
'messages': [{'role': 'user', 'content': prompt}],
|
||||
'max_tokens': 300,
|
||||
'temperature': 0.5
|
||||
}
|
||||
|
||||
response = requests.post(f'{hermes_endpoint}/chat/completions',
|
||||
headers=headers, json=data, timeout=10)
|
||||
|
||||
print(f"DEBUG: API Status: {response.status_code}")
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
reasoning = result['choices'][0]['message']['content'].strip()
|
||||
print(f"DEBUG: Real API response: {reasoning}")
|
||||
return reasoning
|
||||
else:
|
||||
print(f"DEBUG: API failed with status {response.status_code}: {response.text[:200]}")
|
||||
fallback_move = top_candidates[0] if top_candidates else random.choice([i for i in range(100) if i not in ai_shots])
|
||||
return f"ANALYSIS: Turn {turn_number} suggests targeting high-probability zones based on mathematical analysis. The current hit pattern indicates potential ship orientations that guide strategic decisions. Focusing on adjacent unexplored cells maximizes discovery potential.\n\nMOVE: {fallback_move}"
|
||||
|
||||
except Exception as e:
|
||||
print(f"DEBUG: API exception: {str(e)}")
|
||||
fallback_move = top_candidates[0] if top_candidates else random.choice([i for i in range(100) if i not in ai_shots])
|
||||
return f"ANALYSIS: After {turn_number} turns, probability analysis guides optimal targeting strategies. Current data suggests focusing on clustered high-value positions for maximum efficiency. Strategic patience combined with mathematical precision will yield victory.\n\nMOVE: {fallback_move}"
|
||||
|
||||
# AI chooses a shot
|
||||
def choose_ai_shot():
|
||||
global can_fit_ship, update_probability, generate_hunt_targets, random_search, probability_matrix, ai_mode, ai_shots, random, user_board, ai_hits, ai_hit_result, hermes_reason_move, ship_sizes, ai_sunk_ships
|
||||
|
||||
if ai_mode == "hermes_reasoner":
|
||||
# Use probability algorithm + Hermes reasoning
|
||||
|
||||
# Update probability matrix based on shots
|
||||
remaining_ships = [ship for ship in ship_sizes.keys() if ship not in ai_sunk_ships]
|
||||
remaining_ship_sizes = [ship_sizes[ship] for ship in remaining_ships]
|
||||
print(f"DEBUG: Remaining ships: {remaining_ships}")
|
||||
print(f"DEBUG: Total shots: {len(ai_shots)}, Hits: {len(ai_hits)}, Misses: {len(ai_shots) - len(ai_hits)}")
|
||||
|
||||
# Recalculate entire probability matrix
|
||||
new_probability_matrix = [[0] * 10 for _ in range(10)]
|
||||
|
||||
for y in range(10):
|
||||
for x in range(10):
|
||||
pos = y * 10 + x
|
||||
if pos in ai_shots:
|
||||
new_probability_matrix[y][x] = 0 # Already shot
|
||||
else:
|
||||
# Count how many ship placements could use this cell
|
||||
for ship_size in remaining_ship_sizes:
|
||||
# Check horizontal placements
|
||||
for start_x in range(max(0, x - ship_size + 1), min(x + 1, 10 - ship_size + 1)):
|
||||
valid = True
|
||||
includes_hit = False
|
||||
for dx in range(ship_size):
|
||||
check_pos = y * 10 + (start_x + dx)
|
||||
if check_pos in ai_shots and check_pos not in ai_hits:
|
||||
valid = False # Ship can't go through a miss
|
||||
break
|
||||
if check_pos in ai_hits:
|
||||
includes_hit = True
|
||||
if valid:
|
||||
# Base probability for valid placement
|
||||
new_probability_matrix[y][x] += 1
|
||||
# Bonus if it includes a hit
|
||||
if includes_hit:
|
||||
new_probability_matrix[y][x] += 10
|
||||
|
||||
# Check vertical placements
|
||||
for start_y in range(max(0, y - ship_size + 1), min(y + 1, 10 - ship_size + 1)):
|
||||
valid = True
|
||||
includes_hit = False
|
||||
for dy in range(ship_size):
|
||||
check_pos = (start_y + dy) * 10 + x
|
||||
if check_pos in ai_shots and check_pos not in ai_hits:
|
||||
valid = False # Ship can't go through a miss
|
||||
break
|
||||
if check_pos in ai_hits:
|
||||
includes_hit = True
|
||||
if valid:
|
||||
# Base probability for valid placement
|
||||
new_probability_matrix[y][x] += 1
|
||||
# Bonus if it includes a hit
|
||||
if includes_hit:
|
||||
new_probability_matrix[y][x] += 10
|
||||
|
||||
# Replace the old matrix with the new one
|
||||
probability_matrix = new_probability_matrix
|
||||
|
||||
# Boost probabilities around unsunk hits
|
||||
for hit_pos in ai_hits:
|
||||
hit_x, hit_y = hit_pos % 10, hit_pos // 10
|
||||
# Check if this hit is part of a sunk ship
|
||||
hit_is_sunk = False
|
||||
for ship_name in ai_sunk_ships:
|
||||
# This would need ship position tracking to work properly
|
||||
pass # Skip for now, assume all hits need chasing
|
||||
|
||||
if not hit_is_sunk:
|
||||
# Boost adjacent cells
|
||||
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
|
||||
adj_x, adj_y = hit_x + dx, hit_y + dy
|
||||
if 0 <= adj_x < 10 and 0 <= adj_y < 10:
|
||||
adj_pos = adj_y * 10 + adj_x
|
||||
if adj_pos not in ai_shots:
|
||||
# Only boost if not already boosted
|
||||
if probability_matrix[adj_y][adj_x] < 50:
|
||||
probability_matrix[adj_y][adj_x] = 50 # Set to fixed high value instead of adding
|
||||
|
||||
# Find top 6 highest probability positions
|
||||
position_probs = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots: # Only consider unshot positions
|
||||
x, y = i % 10, i // 10
|
||||
position_probs.append((probability_matrix[y][x], i))
|
||||
|
||||
# Sort by probability (descending) and take top positions
|
||||
position_probs.sort(reverse=True)
|
||||
candidates = [pos for prob, pos in position_probs[:20]] # Take top 20 for variety
|
||||
max_prob = position_probs[0][0] if position_probs else 0
|
||||
|
||||
# Fallback if no candidates found
|
||||
if not candidates:
|
||||
candidates = [i for i in range(100) if i not in ai_shots]
|
||||
|
||||
# Debug: Log what we're working with
|
||||
turn_number = len(ai_shots) + 1
|
||||
print(f"DEBUG: Turn {turn_number}, Max prob: {max_prob}")
|
||||
print("DEBUG: Probability grid:")
|
||||
for y in range(10):
|
||||
row = [f"{probability_matrix[y][x]:2d}" for x in range(10)]
|
||||
print(f" {' '.join(row)}")
|
||||
print(f"DEBUG: Top candidates: {candidates[:10]}")
|
||||
|
||||
reasoning_response = hermes_reason_move("battleship", turn_number, candidates)
|
||||
|
||||
# Analysis already logged in hermes_reason_move function
|
||||
|
||||
# Extract move from response - try multiple parsing methods
|
||||
try:
|
||||
if "MOVE:" in reasoning_response:
|
||||
move_part = reasoning_response.split("MOVE:")[1].strip()
|
||||
ai_shot = int(move_part.split()[0])
|
||||
print(f"DEBUG: Hermes Move: {ai_shot} (from 'MOVE: {move_part.split()[0]}')")
|
||||
else:
|
||||
# Fallback: extract any number from the response that's in candidates
|
||||
import re
|
||||
numbers = re.findall(r'\b(\d+)\b', reasoning_response)
|
||||
valid_moves = [int(n) for n in numbers if int(n) in candidates and int(n) not in ai_shots]
|
||||
if valid_moves:
|
||||
ai_shot = valid_moves[0]
|
||||
print(f"DEBUG: Hermes Move (parsed): {ai_shot} from numbers {numbers}")
|
||||
else:
|
||||
raise Exception(f"ERROR: Hermes response had no valid moves! Response: {reasoning_response}, Candidates: {candidates}")
|
||||
|
||||
# Validate the shot is legal
|
||||
if ai_shot in ai_shots or ai_shot < 0 or ai_shot > 99:
|
||||
ai_shot = random.choice(candidates)
|
||||
print(f"DEBUG: Invalid shot, using fallback: {ai_shot}")
|
||||
|
||||
except Exception as e:
|
||||
ai_shot = random.choice(candidates)
|
||||
print(f"DEBUG: Parse error: {e}, using fallback: {ai_shot}")
|
||||
|
||||
elif ai_mode == "super_hunter":
|
||||
# Use probabilistic grid algorithm
|
||||
max_prob = 0
|
||||
candidates = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots: # Exclude already-fired cells
|
||||
x, y = i % 10, i // 10
|
||||
if probability_matrix[y][x] > max_prob:
|
||||
max_prob = probability_matrix[y][x]
|
||||
candidates = [i]
|
||||
elif probability_matrix[y][x] == max_prob:
|
||||
candidates.append(i)
|
||||
ai_shot = random.choice(candidates)
|
||||
elif ai_mode == "hunter":
|
||||
# Simple hunter mode logic
|
||||
if hits:
|
||||
# Target adjacent cells of the last hit
|
||||
last_hit = hits[-1]
|
||||
hunt_targets = generate_hunt_targets(last_hit, ai_shots)
|
||||
if hunt_targets:
|
||||
ai_shot = hunt_targets.pop(0)
|
||||
else:
|
||||
ai_shot = random_search()
|
||||
else:
|
||||
ai_shot = random_search()
|
||||
else:
|
||||
# Random mode
|
||||
ai_shot = random_search()
|
||||
|
||||
# Update AI state after the shot
|
||||
if user_board[ai_shot] != -1:
|
||||
ai_hits.append(ai_shot)
|
||||
ai_hit_result = "hit"
|
||||
if ai_mode == "super_hunter" or ai_mode == "hermes_reasoner":
|
||||
update_probability(ai_shot % 10, ai_shot // 10, True)
|
||||
else:
|
||||
ai_hit_result = "miss"
|
||||
if ai_mode == "super_hunter" or ai_mode == "hermes_reasoner":
|
||||
update_probability(ai_shot % 10, ai_shot // 10, False)
|
||||
|
||||
return ai_shot
|
||||
|
||||
# Function for random search
|
||||
def random_search():
|
||||
available_positions = []
|
||||
for i in range(100):
|
||||
if i not in ai_shots:
|
||||
available_positions.append(i)
|
||||
return random.choice(available_positions)
|
||||
|
||||
# Function to generate hunt targets around a hit
|
||||
def generate_hunt_targets(hit_position, ai_shots):
|
||||
potential_targets = []
|
||||
row, col = divmod(hit_position, 10)
|
||||
|
||||
# Up
|
||||
if row > 0:
|
||||
potential_targets.append(hit_position - 10)
|
||||
# Down
|
||||
if row < 9:
|
||||
potential_targets.append(hit_position + 10)
|
||||
# Left
|
||||
if col > 0:
|
||||
potential_targets.append(hit_position - 1)
|
||||
# Right
|
||||
if col < 9:
|
||||
potential_targets.append(hit_position + 1)
|
||||
|
||||
# Filter out already fired positions
|
||||
filtered_targets = []
|
||||
for pos in potential_targets:
|
||||
if pos not in ai_shots:
|
||||
filtered_targets.append(pos)
|
||||
return filtered_targets
|
||||
|
||||
# Get the user's shot
|
||||
try:
|
||||
user_shot = int(metadata.get("user_shot"))
|
||||
except (IndexError, ValueError) as e:
|
||||
user_shot = -1
|
||||
|
||||
if game_over:
|
||||
script_result = {
|
||||
"metadata": {
|
||||
"game_over": True,
|
||||
"user_wins": user_wins,
|
||||
"ai_wins": ai_wins
|
||||
}
|
||||
}
|
||||
print(f"DEBUG: Game over detected! User wins: {user_wins}, AI wins: {ai_wins}")
|
||||
elif 0 <= user_shot < 100 and user_shot not in user_shots:
|
||||
# The move is valid
|
||||
user_shots.append(user_shot)
|
||||
user_hit_result = "miss"
|
||||
if ai_board[user_shot] != -1:
|
||||
user_hits.append(user_shot)
|
||||
user_hit_result = "hit"
|
||||
|
||||
# AI makes a move
|
||||
ai_shot = choose_ai_shot()
|
||||
ai_shots.append(ai_shot)
|
||||
|
||||
# Check if any AI ship is sunk
|
||||
for ship_name in ship_sizes.keys():
|
||||
if check_sunk(ai_board, user_hits, ship_name) and ship_name not in user_sunk_ships:
|
||||
user_sunk_ships.append(ship_name)
|
||||
user_sunk_ship_this_round = ship_name
|
||||
print(f"DEBUG: USER SUNK AI SHIP: {ship_name}")
|
||||
|
||||
# Check if any User ship is sunk
|
||||
for ship_name in ship_sizes.keys():
|
||||
if check_sunk(user_board, ai_hits, ship_name) and ship_name not in ai_sunk_ships:
|
||||
ai_sunk_ships.append(ship_name)
|
||||
ai_sunk_ship_this_round = ship_name
|
||||
print(f"DEBUG: AI SUNK USER SHIP: {ship_name}")
|
||||
|
||||
# Check if all AI ships are hit
|
||||
all_ai_ships_hit = True
|
||||
for pos in range(100):
|
||||
if ai_board[pos] != -1 and pos not in user_hits:
|
||||
all_ai_ships_hit = False
|
||||
break
|
||||
|
||||
# Check if all User ships are hit
|
||||
all_user_ships_hit = True
|
||||
for pos in range(100):
|
||||
if user_board[pos] != -1 and pos not in ai_hits:
|
||||
all_user_ships_hit = False
|
||||
break
|
||||
|
||||
if all_ai_ships_hit:
|
||||
game_over = True
|
||||
user_wins = True
|
||||
ai_wins = False
|
||||
print(f"DEBUG: USER WINS! All AI ships destroyed. Game over.")
|
||||
elif all_user_ships_hit:
|
||||
game_over = True
|
||||
user_wins = False
|
||||
ai_wins = True
|
||||
print(f"DEBUG: AI WINS! All user ships destroyed. Game over.")
|
||||
|
||||
# Only track winning move if there's exactly 1 position left (for next turn's categorization)
|
||||
user_winning_move = None
|
||||
ai_winning_move = None
|
||||
|
||||
# Check which user move would win the game (AI ship positions left)
|
||||
ai_ship_positions_left = [pos for pos in range(100) if ai_board[pos] != -1 and pos not in user_hits]
|
||||
if len(ai_ship_positions_left) == 1:
|
||||
user_winning_move = ai_ship_positions_left[0]
|
||||
print(f"DEBUG: User has exactly 1 winning move at position {user_winning_move}")
|
||||
else:
|
||||
print(f"DEBUG: User has {len(ai_ship_positions_left)} AI positions left - no winning move")
|
||||
|
||||
# Check which AI move would win the game (user ship positions left)
|
||||
user_ship_positions_left = [pos for pos in range(100) if user_board[pos] != -1 and pos not in ai_hits]
|
||||
if len(user_ship_positions_left) == 1:
|
||||
ai_winning_move = user_ship_positions_left[0]
|
||||
print(f"DEBUG: AI has exactly 1 winning move at position {ai_winning_move}")
|
||||
else:
|
||||
print(f"DEBUG: AI has {len(user_ship_positions_left)} user positions left - no winning move")
|
||||
|
||||
# Plot the boards
|
||||
fig, axs = plt.subplots(1, 2, figsize=(12, 6))
|
||||
fig.suptitle("Battleship", fontsize=16)
|
||||
|
||||
# User's view of AI's board
|
||||
axs[0].set_xlim(0, 10)
|
||||
axs[0].set_ylim(0, 10)
|
||||
axs[0].set_xticks([])
|
||||
axs[0].set_yticks([])
|
||||
axs[0].grid(True)
|
||||
axs[0].set_title("Your Shots", fontsize=12)
|
||||
|
||||
# Plot user shots on AI's board
|
||||
for i in range(100):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if i in user_shots:
|
||||
if i in user_hits:
|
||||
axs[0].text(x + 0.5, y + 0.5, 'X', fontsize=12, ha='center', va='center', color='red')
|
||||
else:
|
||||
axs[0].text(x + 0.5, y + 0.5, 'O', fontsize=12, ha='center', va='center', color='black')
|
||||
axs[0].text(x + 0.5, y + 0.5, str(i), fontsize=8, ha='center', va='center', color='gray')
|
||||
|
||||
# AI's view of User's board
|
||||
axs[1].set_xlim(0, 10)
|
||||
axs[1].set_ylim(0, 10)
|
||||
axs[1].set_xticks([])
|
||||
axs[1].set_yticks([])
|
||||
axs[1].grid(True)
|
||||
axs[1].set_title("Your Ships", fontsize=12)
|
||||
|
||||
# Plot user ships
|
||||
for i, ship in enumerate(user_board):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if ship != -1:
|
||||
axs[1].add_patch(plt.Rectangle((x, y), 1, 1, color=ship_colors[ship], alpha=0.5))
|
||||
|
||||
# Plot AI shots on User's board
|
||||
for i in range(100):
|
||||
x, y = i % 10, 9 - i // 10
|
||||
if i in ai_shots:
|
||||
if i in ai_hits:
|
||||
axs[1].text(x + 0.5, y + 0.5, 'X', fontsize=12, ha='center', va='center', color='red')
|
||||
else:
|
||||
axs[1].text(x + 0.5, y + 0.5, 'O', fontsize=12, ha='center', va='center', color='black')
|
||||
axs[1].text(x + 0.5, y + 0.5, str(i), fontsize=8, ha='center', va='center', color='gray')
|
||||
|
||||
# Draw lines across sunk ships
|
||||
for ship_name in user_sunk_ships:
|
||||
draw_line(axs[0], ai_board, ship_name)
|
||||
|
||||
for ship_name in ai_sunk_ships:
|
||||
draw_line(axs[1], user_board, ship_name)
|
||||
|
||||
# Add legend
|
||||
handles = []
|
||||
for color in ship_colors.values():
|
||||
handles.append(plt.Rectangle((0, 0), 1, 1, color=color, alpha=0.5))
|
||||
axs[1].legend(handles, ship_colors.keys(), loc='upper right', fontsize=8)
|
||||
|
||||
buf = io.BytesIO()
|
||||
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.1)
|
||||
plt.close(fig)
|
||||
buf.seek(0)
|
||||
plot_image = base64.b64encode(buf.getvalue()).decode('utf-8')
|
||||
|
||||
# gpt-4: If "plot_image" is in the result, set it as the background image
|
||||
print(f"DEBUG: Setting metadata for feedback - user_sunk_ship_this_round: {user_sunk_ship_this_round}, ai_sunk_ship_this_round: {ai_sunk_ship_this_round}")
|
||||
|
||||
script_result = {
|
||||
"plot_image": plot_image,
|
||||
"set_background": True,
|
||||
"metadata": {
|
||||
"user_board": user_board,
|
||||
"ai_board": ai_board,
|
||||
"user_shot": user_shot,
|
||||
"ai_shot": ai_shot,
|
||||
"user_shots": user_shots,
|
||||
"ai_shots": ai_shots,
|
||||
"user_hits": user_hits,
|
||||
"ai_hits": ai_hits,
|
||||
"game_over": game_over,
|
||||
"user_wins": user_wins,
|
||||
"ai_wins": ai_wins,
|
||||
"user_hit_result": user_hit_result,
|
||||
"ai_hit_result": ai_hit_result,
|
||||
"user_sunk_ships": user_sunk_ships,
|
||||
"ai_sunk_ships": ai_sunk_ships,
|
||||
"user_sunk_ship_this_round": user_sunk_ship_this_round,
|
||||
"ai_sunk_ship_this_round": ai_sunk_ship_this_round,
|
||||
"ai_mode": ai_mode,
|
||||
"probability_matrix": probability_matrix,
|
||||
"hits": hits,
|
||||
"misses": misses,
|
||||
"sunk_ships": sunk_ships,
|
||||
"user_winning_move": user_winning_move,
|
||||
"ai_winning_move": ai_winning_move
|
||||
}
|
||||
}
|
||||
|
||||
# Check if this was a winning move and override transition
|
||||
if game_over:
|
||||
script_result["next_section_and_step"] = "section_1:step_3"
|
||||
print(f"POST-SCRIPT: Game over detected, overriding transition to step_3")
|
||||
else:
|
||||
script_result = {
|
||||
"error": f"Invalid shot: {metadata.get('user_shot')}",
|
||||
"metadata": {}
|
||||
}
|
||||
|
||||
buckets:
|
||||
- valid_move
|
||||
- invalid_move
|
||||
- exit
|
||||
- restart
|
||||
transitions:
|
||||
valid_move:
|
||||
run_processing_script: True
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
The user shot seems valid.
|
||||
metadata_tmp_add:
|
||||
user_shot: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
invalid_move:
|
||||
content_blocks:
|
||||
- "That move is invalid. Please choose a position between 0 and 99."
|
||||
metadata_tmp_add:
|
||||
user_shot: "the-users-response"
|
||||
next_section_and_step: "section_1:step_2"
|
||||
exit:
|
||||
next_section_and_step: "section_1:step_4"
|
||||
restart:
|
||||
content_blocks:
|
||||
- "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "Game Over"
|
||||
question: "Would you like to restart and play again, or would you prefer to exit?"
|
||||
tokens_for_ai: |
|
||||
If the user wants to restart or play again, categorize as 'restart'.
|
||||
If the user wants to exit, categorize as 'exit'.
|
||||
buckets:
|
||||
- restart
|
||||
- exit
|
||||
transitions:
|
||||
restart:
|
||||
content_blocks:
|
||||
- "Restarting the game. Let's start fresh!"
|
||||
metadata_clear: True
|
||||
next_section_and_step: "section_1:step_0"
|
||||
exit:
|
||||
content_blocks:
|
||||
- "Thank you for playing Battleship! 🎉"
|
||||
- "Feel free to come back anytime for another game."
|
||||
next_section_and_step: "section_1:step_4"
|
||||
|
||||
- step_id: "step_4"
|
||||
title: "Goodbye"
|
||||
content_blocks:
|
||||
- "Thanks for playing! Hope you enjoyed the battle at sea."
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Elephants"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is an Elephant?"
|
||||
content_blocks:
|
||||
- "Welcome to the world of elephants!"
|
||||
- "Elephants are the largest land animals on Earth. They are known for their big ears, long trunks, and tusks."
|
||||
tokens_for_ai: "Explain what an elephant is and its key features in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you know about elephants?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know a lot about elephants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about elephants. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on elephants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of elephants in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Where Do Elephants Live?"
|
||||
content_blocks:
|
||||
- "Elephants live in different parts of the world."
|
||||
- "There are two main types of elephants: African elephants and Asian elephants."
|
||||
- "African elephants live in Africa, and Asian elephants live in Asia."
|
||||
tokens_for_ai: "Explain where elephants live and the difference between African and Asian elephants in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name the two types of elephants and where they live?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know where elephants live."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about where elephants live. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on where elephants live."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of where elephants live in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Elephant Anatomy"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Elephant Trunks"
|
||||
content_blocks:
|
||||
- "Elephants have long trunks that they use for many things."
|
||||
- "They use their trunks to drink water, pick up food, and even to greet other elephants."
|
||||
tokens_for_ai: "Explain the uses of an elephant's trunk in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do elephants use their trunks for?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how elephants use their trunks."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about how elephants use their trunks. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on elephant trunks."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of elephant trunks in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Elephant Ears"
|
||||
content_blocks:
|
||||
- "Elephants have big ears that help them stay cool."
|
||||
- "They flap their ears to fan themselves and keep their bodies cool."
|
||||
tokens_for_ai: "Explain the purpose of an elephant's ears in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do elephants have big ears?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know why elephants have big ears."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about why elephants have big ears. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on elephant ears."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of elephant ears in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Elephant Behavior"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Elephant Families"
|
||||
content_blocks:
|
||||
- "Elephants live in groups called herds."
|
||||
- "A herd is usually led by the oldest female elephant, called the matriarch."
|
||||
tokens_for_ai: "Explain the social structure of elephant herds in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is a group of elephants called and who leads it?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about elephant families."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about elephant families. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on elephant families."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of elephant families in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Elephant Communication"
|
||||
content_blocks:
|
||||
- "Elephants communicate with each other using sounds, touch, and even vibrations."
|
||||
- "They can make loud trumpeting sounds and low rumbles that humans can't hear."
|
||||
tokens_for_ai: "Explain how elephants communicate in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do elephants communicate with each other?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how elephants communicate."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about how elephants communicate. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on elephant communication."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of elephant communication in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Elephant Conservation"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Why Elephants Need Our Help"
|
||||
content_blocks:
|
||||
- "Elephants are amazing animals, but they need our help to survive."
|
||||
- "Many elephants are in danger because of habitat loss and poaching."
|
||||
tokens_for_ai: "Explain why elephants need our help and the threats they face in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why do elephants need our help?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand why elephants need our help."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about why elephants need our help. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the child's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on why elephants need our help."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of why elephants need our help in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "How We Can Help Elephants"
|
||||
content_blocks:
|
||||
- "There are many ways we can help elephants."
|
||||
- "We can support organizations that protect elephants, learn more about them, and spread the word to others."
|
||||
tokens_for_ai: "Explain how we can help elephants in a friendly and engaging manner suitable for a 7-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you think of ways to help elephants?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You have great ideas to help elephants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the child to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have some good ideas. Let's think of more ways to help elephants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional suggestions to help the child think of more ways to help elephants in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on how we can help elephants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the child back to the topic of how we can help elephants in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the child's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "You're an Elephant Expert!"
|
||||
content_blocks:
|
||||
- "🎉 Congratulations! You've learned so much about elephants today!"
|
||||
- "You now know:"
|
||||
- "✅ What elephants look like and how big they are"
|
||||
- "✅ What elephants eat with their trunks"
|
||||
- "✅ How elephants communicate with each other"
|
||||
- "✅ Why elephants need our help"
|
||||
- "✅ Ways we can help protect elephants"
|
||||
- "You're now an elephant expert! Keep learning and caring about animals! 🐘🌟"
|
||||
- "Thank you for taking this journey with us!"
|
||||
|
|
@ -1,598 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s performance throughout the logic puzzle activity.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their ability to reason through logical statements
|
||||
|
||||
- Understanding of deductive reasoning
|
||||
|
||||
- Improvement over the course of the activity
|
||||
|
||||
- Engagement with explanations
|
||||
|
||||
|
||||
Provide encouraging feedback and suggest areas for continued practice.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Logic Puzzles
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome to Logic Puzzles
|
||||
content_blocks:
|
||||
- '# Welcome to Critical Thinking & Logic Puzzles!'
|
||||
- In this activity, you'll develop your logical reasoning skills through a series of engaging puzzles.
|
||||
- You'll learn to identify logical patterns, make deductions, and think critically.
|
||||
- '**What you''ll learn:**'
|
||||
- '- How to analyze logical statements'
|
||||
- '- Deductive reasoning techniques'
|
||||
- '- Pattern recognition'
|
||||
- '- How to avoid common logical fallacies'
|
||||
- ''
|
||||
- Let's begin your journey into the world of logic!
|
||||
question: Are you ready to sharpen your logical thinking skills?
|
||||
tokens_for_ai: 'The student is expressing readiness to begin. Accept any positive, affirming response.
|
||||
|
||||
Categorize as:
|
||||
|
||||
- ready: Student is ready to proceed
|
||||
|
||||
- set_language: Student is setting language preference
|
||||
|
||||
- off_topic: Completely unrelated response
|
||||
|
||||
'
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- Excellent! Let's start with the fundamentals of logical reasoning.
|
||||
next_section_and_step: section_1:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate with you in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on beginning our logic journey. Are you ready to start?
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: section_1
|
||||
title: Basic Logical Statements
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Understanding Logical Statements
|
||||
content_blocks:
|
||||
- '## Understanding Logical Statements'
|
||||
- Logic is about drawing valid conclusions from given information.
|
||||
- ''
|
||||
- '**Basic principle:** If A is true, and ''A implies B'' is true, then B must be true.'
|
||||
- ''
|
||||
- '**Example:**'
|
||||
- '- Statement 1: All cats are mammals.'
|
||||
- '- Statement 2: Whiskers is a cat.'
|
||||
- '- Conclusion: Therefore, Whiskers is a mammal.'
|
||||
- ''
|
||||
- This is called **deductive reasoning** - going from general rules to specific cases.
|
||||
question: Based on this reasoning, if 'All birds have feathers' and 'A robin is a bird', what can we conclude?
|
||||
tokens_for_ai: 'The student should conclude that a robin has feathers.
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: States that robin has feathers (exact wording doesn''t matter)
|
||||
|
||||
- partial_understanding: Mentions birds or feathers but incomplete reasoning
|
||||
|
||||
- limited_effort: Very brief or unclear answer
|
||||
|
||||
- off_topic: Unrelated response
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide feedback on their logical reasoning. If incorrect, gently explain the deductive
|
||||
|
||||
process: since ALL birds have feathers, and a robin IS a bird, then the robin must have feathers.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Praise their correct deductive reasoning and encourage them to continue.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_1:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge what they got right, then gently guide them to the complete answer.
|
||||
next_section_and_step: section_1:step_2
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Encourage them to think more carefully about the logical structure and try again.
|
||||
next_section_and_step: section_1:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's stay focused on the logic puzzle. Think about what we can deduce from the two statements.
|
||||
next_section_and_step: section_1:step_1
|
||||
- step_id: step_2
|
||||
title: The Contrapositive
|
||||
content_blocks:
|
||||
- '## The Contrapositive'
|
||||
- Great! Now let's learn about the **contrapositive** - a powerful logical tool.
|
||||
- ''
|
||||
- 'If we know: ''If A, then B'' is true'
|
||||
- 'Then we also know: ''If NOT B, then NOT A'' is true'
|
||||
- ''
|
||||
- '**Example:**'
|
||||
- '- Original: ''If it''s raining, then the ground is wet'''
|
||||
- '- Contrapositive: ''If the ground is NOT wet, then it''s NOT raining'''
|
||||
- ''
|
||||
- Both statements are logically equivalent!
|
||||
- ''
|
||||
- '**Practice:** We know: ''If you study hard, you will pass the test.'''
|
||||
question: What is the contrapositive of this statement?
|
||||
tokens_for_ai: 'The correct contrapositive is: "If you don''t pass the test, then you didn''t study hard"
|
||||
|
||||
or any equivalent phrasing.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Correctly identifies the contrapositive (not passing → didn''t study)
|
||||
|
||||
- partial_understanding: Gets the concept but reverses incorrectly or incomplete
|
||||
|
||||
- logical_error: Confuses with converse or inverse
|
||||
|
||||
- limited_effort: Very brief or doesn''t attempt to construct the statement
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, praise their understanding. If incorrect, explain that the contrapositive
|
||||
|
||||
negates both parts AND reverses them. Common error: converse (if B then A) is NOT
|
||||
|
||||
logically equivalent to the original.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- logical_error
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent work! You've grasped an important logical concept. Explain why contrapositives are useful in reasoning.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're on the right track. Explain the contrapositive clearly and encourage them.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
logical_error:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Explain the difference between contrapositive, converse, and inverse. Give them another example.
|
||||
next_section_and_step: section_1:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Take your time. Remember: negate both parts AND reverse the order.'
|
||||
next_section_and_step: section_1:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on constructing the contrapositive statement.
|
||||
next_section_and_step: section_1:step_2
|
||||
- section_id: section_2
|
||||
title: Syllogisms and Deduction
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Classic Syllogism Puzzle
|
||||
content_blocks:
|
||||
- '## Classic Syllogism Puzzle'
|
||||
- A **syllogism** is a form of logical argument with two premises and a conclusion.
|
||||
- ''
|
||||
- '**Here''s your puzzle:**'
|
||||
- ''
|
||||
- '**Premise 1:** All philosophers love wisdom.'
|
||||
- '**Premise 2:** Socrates is a philosopher.'
|
||||
- '**Premise 3:** No one who loves wisdom is foolish.'
|
||||
- ''
|
||||
- What can we logically conclude about Socrates?
|
||||
question: What must be true about Socrates based on these premises?
|
||||
tokens_for_ai: 'The correct conclusion is that Socrates is not foolish (or Socrates loves wisdom, which also leads to not being foolish).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: States Socrates is not foolish, or loves wisdom, or both
|
||||
|
||||
- partial_understanding: Gets one conclusion but not the full chain of reasoning
|
||||
|
||||
- limited_effort: Too brief or unclear
|
||||
|
||||
- off_topic: Unrelated or makes up facts not in premises
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Guide them through the logical chain if needed:
|
||||
|
||||
1. Socrates is a philosopher
|
||||
|
||||
2. All philosophers love wisdom → Socrates loves wisdom
|
||||
|
||||
3. No one who loves wisdom is foolish → Socrates is not foolish
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent deductive reasoning! You followed the logical chain perfectly.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good start! Can you extend your reasoning further using all three premises?
|
||||
next_section_and_step: section_2:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Try working through each premise step by step. What do we know about philosophers? What do we know about Socrates?
|
||||
next_section_and_step: section_2:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Focus only on what the premises tell us. What can we deduce step by step?
|
||||
next_section_and_step: section_2:step_1
|
||||
- step_id: step_2
|
||||
title: Truth Tables and Logical Consistency
|
||||
content_blocks:
|
||||
- '## Truth Tables and Logical Consistency'
|
||||
- Sometimes we need to check if statements are consistent with each other.
|
||||
- ''
|
||||
- '**The Scenario:**'
|
||||
- 'Three friends make the following statements:'
|
||||
- ''
|
||||
- '**Alice:** ''If Bob is telling the truth, then Carol is lying.'''
|
||||
- '**Bob:** ''I am telling the truth.'''
|
||||
- '**Carol:** ''Alice is telling the truth.'''
|
||||
- ''
|
||||
- Let's assume Bob IS telling the truth (as he claims).
|
||||
question: If Bob is telling the truth, is there a logical contradiction? If so, where?
|
||||
tokens_for_ai: 'Let''s work through this:
|
||||
|
||||
- If Bob is telling the truth (as assumed)
|
||||
|
||||
- Then by Alice''s statement, Carol must be lying
|
||||
|
||||
- But Carol says "Alice is telling the truth"
|
||||
|
||||
- If Carol is lying (as we deduced), then Alice must be lying
|
||||
|
||||
- But this contradicts our assumption that Alice''s statement about Bob/Carol is valid
|
||||
|
||||
|
||||
Student should identify that there IS a contradiction, or that Carol must be lying.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Identifies the contradiction or that Carol must be lying
|
||||
|
||||
- partial_understanding: Sees some inconsistency but doesn''t fully explain it
|
||||
|
||||
- confused: Gets lost in the logic
|
||||
|
||||
- limited_effort: Very brief answer
|
||||
|
||||
- asking_clarifying_questions: Requests help or clarification
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they''re struggling, walk through it step by step. This is a harder puzzle, so be
|
||||
|
||||
encouraging. The key insight is following the chain of implications.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Brilliant! You navigated a complex logical scenario. Explain the full chain of reasoning.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're getting there! Let's trace through what each statement implies step by step.
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
confused:
|
||||
content_blocks:
|
||||
- 'Let''s break it down:'
|
||||
- 1. Assume Bob tells the truth
|
||||
- 2. What does Alice's statement tell us about Carol?
|
||||
- 3. What does Carol's statement tell us about Alice?
|
||||
- 4. Do these work together?
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Take your time and work through each person's statement carefully.
|
||||
next_section_and_step: section_2:step_2
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question and provide helpful hints about how to approach the problem.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_2:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on analyzing the logical consistency of the three statements.
|
||||
next_section_and_step: section_2:step_2
|
||||
- section_id: section_3
|
||||
title: Knights and Knaves
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Island of Knights and Knaves
|
||||
content_blocks:
|
||||
- '## The Island of Knights and Knaves'
|
||||
- This is a classic logic puzzle type!
|
||||
- ''
|
||||
- '**The Rules:**'
|
||||
- '- Knights ALWAYS tell the truth'
|
||||
- '- Knaves ALWAYS lie'
|
||||
- '- Everyone is either a knight or a knave'
|
||||
- ''
|
||||
- '**The Puzzle:**'
|
||||
- You meet two people, A and B.
|
||||
- ''
|
||||
- '**Person A says:** ''At least one of us is a knave.'''
|
||||
- ''
|
||||
- What are A and B?
|
||||
question: Is A a knight or a knave? Is B a knight or a knave? Explain your reasoning.
|
||||
tokens_for_ai: "Solution:\n- If A is a knave (liar), then the statement \"at least one of us is a knave\" would be false,\n meaning both are knights. But A can't be both a knight and a knave - contradiction!\n- Therefore A must be a knight (truth-teller)\n- Since A tells the truth, \"at least one of us is a knave\" is true\n- Since A is a knight, B must be the knave\n\nAnswer: A is a knight, B is a knave\n\nCategorize as:\n- correct: Identifies A as knight and B as knave with reasonable explanation\n- partial_understanding: Gets one correct but not both, or right answer without clear reasoning\n- logical_error: Makes an error in the logical deduction\n- limited_effort: Too brief or gives up\n- asking_clarifying_questions: Asks for help\n- off_topic: Unrelated\n"
|
||||
feedback_tokens_for_ai: 'This is a challenging puzzle! If they get stuck, suggest trying both possibilities:
|
||||
|
||||
"What if A is a knight? What if A is a knave?" and see which leads to a contradiction.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- logical_error
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Outstanding! You've mastered proof by contradiction. This is advanced logical reasoning!
|
||||
metadata_add:
|
||||
score: n+3
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're thinking in the right direction. Try assuming A is a knave and see if that leads to a contradiction.
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
logical_error:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Let''s think through this carefully. Test both possibilities: what if A is a knight? What if A is a knave?'
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'This is challenging! Try starting with: ''Assume A is a knight. Then what must be true?'''
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question helpfully and provide a hint about testing both possibilities.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_3:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- 'Let''s work through the knight and knave puzzle. Remember: knights always tell the truth, knaves always lie.'
|
||||
next_section_and_step: section_3:step_1
|
||||
- step_id: step_2
|
||||
title: Advanced Knights and Knaves
|
||||
content_blocks:
|
||||
- '## Advanced Knights and Knaves'
|
||||
- Ready for a harder one? Let's add a third person!
|
||||
- ''
|
||||
- 'You meet three people: X, Y, and Z.'
|
||||
- ''
|
||||
- '**X says:** ''All of us are knaves.'''
|
||||
- '**Y says:** ''Exactly one of us is a knight.'''
|
||||
- ''
|
||||
- What can you determine about X, Y, and Z?
|
||||
question: Identify whether X, Y, and Z are knights or knaves. Explain your reasoning.
|
||||
tokens_for_ai: 'Solution:
|
||||
|
||||
- X says "all of us are knaves"
|
||||
|
||||
- If X were a knight (truth-teller), then "all are knaves" would be true, but X is a knight - contradiction!
|
||||
|
||||
- Therefore X must be a knave (liar)
|
||||
|
||||
- Since X is a knave, the statement "all of us are knaves" is false, so at least one is a knight
|
||||
|
||||
- Y says "exactly one of us is a knight"
|
||||
|
||||
- If Y is a knave, then "exactly one is a knight" is false, but we know at least one is a knight (not Y, not X)... so Z would be a knight
|
||||
|
||||
- If Y is a knight, then "exactly one is a knight" is true, and Y is that knight, so Z must be a knave
|
||||
|
||||
- Actually, if Y were a knave and Z were a knight, then we''d have exactly one knight (Z), making Y''s statement true - but knaves can''t tell the truth! Contradiction.
|
||||
|
||||
- Therefore Y must be a knight and Z must be a knave
|
||||
|
||||
|
||||
Answer: X is a knave, Y is a knight, Z is a knave
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Correctly identifies all three with solid reasoning
|
||||
|
||||
- partial_understanding: Gets some right or reasoning is incomplete
|
||||
|
||||
- confused: Logic errors or contradictions in their answer
|
||||
|
||||
- limited_effort: Very brief or gives up
|
||||
|
||||
- asking_clarifying_questions: Asks for help
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'This is quite challenging! Encourage their effort. If struggling, suggest working through
|
||||
|
||||
X first (easier), then systematically testing Y as knight vs knave.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Exceptional work! You've demonstrated mastery of complex logical deduction. This is university-level reasoning!
|
||||
metadata_add:
|
||||
score: n+5
|
||||
puzzles_solved: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good progress! Let's work through this systematically. Start with X - can X be a knight?
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
confused:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Let's break this down step by step. First, what can we determine about X from their statement?
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- This is a tough puzzle! Start by analyzing X's statement. Can someone truthfully say 'we are all liars'?
|
||||
metadata_add:
|
||||
hints_used: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question and provide systematic guidance on how to approach the puzzle.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_3:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on solving this three-person knight and knave puzzle.
|
||||
next_section_and_step: section_3:step_2
|
||||
- section_id: section_4
|
||||
title: Reflection and Summary
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Congratulations!
|
||||
content_blocks:
|
||||
- '## Congratulations! 🎉'
|
||||
- You've completed the Logic Puzzles activity!
|
||||
- ''
|
||||
- '**What you''ve learned:**'
|
||||
- ✓ Basic deductive reasoning (if A then B)
|
||||
- ✓ Contrapositives and logical equivalence
|
||||
- ✓ Syllogisms and multi-step deduction
|
||||
- ✓ Truth tables and consistency checking
|
||||
- ✓ Proof by contradiction (Knights and Knaves)
|
||||
- ''
|
||||
- '**Why logical thinking matters:**'
|
||||
- '- Programming and debugging require logical reasoning'
|
||||
- '- Critical thinking helps evaluate arguments and claims'
|
||||
- '- Problem-solving in math, science, and everyday life'
|
||||
- '- Avoiding logical fallacies in discussions'
|
||||
- ''
|
||||
- '**Your journey:**'
|
||||
- You've progressed from basic deductions to complex multi-person logic puzzles.
|
||||
- These skills will serve you well in many areas of thinking and learning!
|
||||
question: What was the most challenging puzzle for you, and what did you learn from it?
|
||||
tokens_for_ai: 'This is a reflection question. Accept any thoughtful response about their learning experience.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- thoughtful_reflection: Provides specific insights about their learning
|
||||
|
||||
- brief_reflection: Short but genuine reflection
|
||||
|
||||
- limited_effort: Very minimal response
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide personalized feedback on their journey through the activity. Acknowledge their
|
||||
|
||||
specific challenges and growth. Encourage continued practice with logical reasoning.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- thoughtful_reflection
|
||||
- brief_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Provide thoughtful, personalized feedback on their learning journey and suggest how to continue developing logical thinking skills.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
brief_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their reflection and encourage them to keep practicing logical reasoning.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for participating and summarize key takeaways from the activity.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's reflect on your logic puzzle journey. Which puzzle challenged you most?
|
||||
next_section_and_step: section_4:step_1
|
||||
|
|
@ -1,784 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s understanding of the scientific method.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their ability to identify steps in the scientific method
|
||||
|
||||
- Understanding of hypothesis formation and testing
|
||||
|
||||
- Recognition of controls and variables
|
||||
|
||||
- Critical thinking about experimental design
|
||||
|
||||
- Engagement with the case studies
|
||||
|
||||
|
||||
Provide encouraging feedback and suggestions for applying scientific thinking in their own explorations.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Scientific Method Explorer
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome to Scientific Method
|
||||
content_blocks:
|
||||
- '# Welcome to Scientific Method Explorer!'
|
||||
- Explore how scientists make discoveries through the scientific method.
|
||||
- ''
|
||||
- 'You''ll follow in the footsteps of famous scientists, learning to:'
|
||||
- '- Ask testable questions'
|
||||
- '- Form hypotheses'
|
||||
- '- Design experiments'
|
||||
- '- Identify variables and controls'
|
||||
- '- Analyze results and draw conclusions'
|
||||
- ''
|
||||
- '**The Scientific Method Steps:**'
|
||||
- 1. **Observe** - Notice something interesting
|
||||
- 2. **Question** - Ask why or how
|
||||
- 3. **Hypothesize** - Make an educated guess
|
||||
- 4. **Experiment** - Test your hypothesis
|
||||
- 5. **Analyze** - Look at your data
|
||||
- 6. **Conclude** - Determine if hypothesis was supported
|
||||
- ''
|
||||
- Ready to think like a scientist?
|
||||
question: Are you ready to explore the scientific method through real discoveries?
|
||||
tokens_for_ai: 'Student is expressing readiness. Accept any positive response.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- ready: Positive, ready to begin
|
||||
|
||||
- set_language: Setting language preference
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- Excellent! Let's begin with a fascinating historical case study.
|
||||
next_section_and_step: section_1:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's get started with exploring science! Are you ready?
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: section_1
|
||||
title: 'Case Study: Germ Theory'
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Mystery of Childbed Fever
|
||||
content_blocks:
|
||||
- '## The Mystery of Childbed Fever (1840s)'
|
||||
- '**The Observation:**'
|
||||
- 'Dr. Ignaz Semmelweis noticed something disturbing in his Vienna hospital:'
|
||||
- '- Ward 1 (doctors and medical students): 10% of mothers died from childbed fever'
|
||||
- '- Ward 2 (midwives): Only 4% of mothers died'
|
||||
- ''
|
||||
- '**The Puzzle:**'
|
||||
- Both wards had similar conditions, but Ward 1 had much higher death rates.
|
||||
- ''
|
||||
- Semmelweis observed that doctors in Ward 1 came directly from autopsy rooms to deliver babies, while midwives in Ward 2 did not perform autopsies.
|
||||
question: What question should Semmelweis ask based on this observation? What do you think might be causing the difference in death rates?
|
||||
tokens_for_ai: 'Good scientific questions might be:
|
||||
|
||||
- Are doctors carrying something deadly from autopsies?
|
||||
|
||||
- Does something on doctors'' hands cause the fever?
|
||||
|
||||
- Is there a connection between autopsies and infections?
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct_question: Identifies a connection between autopsy work and infections
|
||||
|
||||
- partial_understanding: Notices the pattern but doesn''t form a clear causal question
|
||||
|
||||
- creative_thinking: Proposes alternative explanations worth considering
|
||||
|
||||
- limited_effort: Very brief or vague
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they identify the connection to autopsies and handwashing, praise their observation.
|
||||
|
||||
If they suggest other factors, acknowledge the thinking but guide toward the autopsy connection.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct_question
|
||||
- partial_understanding
|
||||
- creative_thinking
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_question:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent scientific observation! You've identified the key question that Semmelweis asked.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
experiments_designed: n+1
|
||||
next_section_and_step: section_1:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good thinking! Can you be more specific about what might be different about the doctors' hands?
|
||||
next_section_and_step: section_1:step_2
|
||||
creative_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Interesting hypothesis! Acknowledge their creativity while guiding them to consider the autopsy connection.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_1:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what the doctors were doing that the midwives were not. What might they be carrying on their hands?
|
||||
next_section_and_step: section_1:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the medical mystery. What difference between the two wards might explain the death rates?
|
||||
next_section_and_step: section_1:step_1
|
||||
- step_id: step_2
|
||||
title: Forming a Hypothesis
|
||||
content_blocks:
|
||||
- '## Forming a Hypothesis'
|
||||
- 'Semmelweis formed a hypothesis:'
|
||||
- ''
|
||||
- '**''Cadaveric particles'' from autopsies on doctors'' hands are causing childbed fever.**'
|
||||
- ''
|
||||
- This was revolutionary! In the 1840s, germs were not yet understood.
|
||||
- ''
|
||||
- '**Now for the experiment:**'
|
||||
- Semmelweis needs to test this hypothesis. He decides to require doctors to wash their hands with chlorinated lime solution before examining patients.
|
||||
- ''
|
||||
- '**Question for you:**'
|
||||
- To make this a good scientific experiment, what should we compare?
|
||||
question: What should Semmelweis measure before and after the handwashing requirement? What would be the control group?
|
||||
tokens_for_ai: 'Good answers should mention:
|
||||
|
||||
- Measure death rates before and after handwashing
|
||||
|
||||
- Compare Ward 1 with handwashing to previous Ward 1 without handwashing
|
||||
|
||||
- Or compare Ward 1 (with handwashing) to Ward 2 (baseline)
|
||||
|
||||
- The control is the previous data or Ward 2
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct_method: Identifies need to compare death rates before/after or between groups
|
||||
|
||||
- partial_understanding: Mentions measuring death rates but unclear on control
|
||||
|
||||
- confused_about_controls: Doesn''t understand the concept of a control group
|
||||
|
||||
- limited_effort: Very brief answer
|
||||
|
||||
- asking_clarifying_questions: Requests explanation of terms
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they understand controls, praise them! If confused about controls, explain that
|
||||
|
||||
a control group helps us know if changes are due to our intervention or something else.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct_method
|
||||
- partial_understanding
|
||||
- confused_about_controls
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_method:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent experimental thinking! You understand the importance of controls in science.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
controls_identified: n+1
|
||||
next_section_and_step: section_1:step_3
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good! You're thinking about measurement. Explain what a control group is and why it's important.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_1:step_3
|
||||
confused_about_controls:
|
||||
content_blocks:
|
||||
- '**Control groups** help us compare results.'
|
||||
- 'We need to know: Are death rates different WITH handwashing vs WITHOUT handwashing?'
|
||||
- That way we know if handwashing made the difference!
|
||||
next_section_and_step: section_1:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what Semmelweis should measure and what he should compare it to.
|
||||
next_section_and_step: section_1:step_2
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about experimental design and controls helpfully.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_1:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on designing the experiment. What should we measure?
|
||||
next_section_and_step: section_1:step_2
|
||||
- step_id: step_3
|
||||
title: The Results!
|
||||
content_blocks:
|
||||
- '## The Results!'
|
||||
- Semmelweis implemented handwashing with chlorinated lime in 1847.
|
||||
- ''
|
||||
- '**The data:**'
|
||||
- '- **Before handwashing (1846):** Death rate in Ward 1 = 10%'
|
||||
- '- **After handwashing (1847-1848):** Death rate in Ward 1 = 2%'
|
||||
- ''
|
||||
- This was a dramatic improvement! The death rate dropped by 80%.
|
||||
- ''
|
||||
- '**Analysis step:**'
|
||||
- Now we must analyze these results and draw a conclusion.
|
||||
question: Based on these results, was Semmelweis's hypothesis supported? What can we conclude about the cause of childbed fever?
|
||||
tokens_for_ai: 'The hypothesis WAS supported - handwashing dramatically reduced death rates, suggesting
|
||||
|
||||
that something on doctors'' hands (cadaveric particles/germs) was indeed causing the fever.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct_conclusion: States hypothesis was supported, handwashing worked, something on hands caused illness
|
||||
|
||||
- partial_understanding: Gets general idea but incomplete reasoning
|
||||
|
||||
- overstating: Claims this "proves" rather than "supports" (good to address scientific certainty)
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, praise their analysis! If they say "proves," gently explain that in science
|
||||
|
||||
we say evidence "supports" a hypothesis rather than "proves" it absolutely.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct_conclusion
|
||||
- partial_understanding
|
||||
- overstating
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_conclusion:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent analysis! You've worked through a complete scientific investigation. Explain the impact this had on medicine.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
case_studies_completed: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good! Can you connect the results more explicitly to the hypothesis about what was on doctors' hands?
|
||||
metadata_add:
|
||||
score: n+1
|
||||
case_studies_completed: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
overstating:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Great thinking! One note: in science we say results ''support'' a hypothesis rather than ''prove'' it. Explain why scientific conclusions are provisional.'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
case_studies_completed: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the dramatic change in death rates. What does this tell us about Semmelweis's hypothesis?
|
||||
next_section_and_step: section_1:step_3
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze the data. Death rates dropped from 10% to 2%. What does this mean?
|
||||
next_section_and_step: section_1:step_3
|
||||
- section_id: section_2
|
||||
title: Design Your Own Experiment
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Newton's Light Experiment
|
||||
content_blocks:
|
||||
- '## Newton''s Light Experiment'
|
||||
- Let's explore another famous case, then YOU'LL design an experiment!
|
||||
- ''
|
||||
- '**The Observation (1660s):**'
|
||||
- Isaac Newton observed that sunlight passing through a prism splits into rainbow colors.
|
||||
- ''
|
||||
- '**The Common Belief:**'
|
||||
- Most people thought the prism was adding color to the light, like stained glass adds color.
|
||||
- ''
|
||||
- '**Newton''s Hypothesis:**'
|
||||
- 'Newton proposed something radical: White light is actually MADE of all the colors combined, and the prism just separates them.'
|
||||
- ''
|
||||
- '**Your Task:**'
|
||||
- Newton needs to prove that the colors come FROM the white light, not from the prism.
|
||||
question: Design an experiment that could test whether the colors are already in white light or are created by the prism. What would you do?
|
||||
tokens_for_ai: 'Newton''s actual experiment: He used a second prism to recombine the separated colors
|
||||
|
||||
back into white light. If the prism created the colors, you couldn''t get white light back.
|
||||
|
||||
|
||||
Good student answers might suggest:
|
||||
|
||||
- Using a second prism to recombine colors
|
||||
|
||||
- Testing different prisms (if prism creates color, different prisms would create different colors)
|
||||
|
||||
- Blocking some colors and seeing what recombines
|
||||
|
||||
- Comparing different light sources
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- excellent_design: Proposes recombining colors or testing multiple prisms
|
||||
|
||||
- creative_approach: Different but scientifically sound experiment
|
||||
|
||||
- partial_understanding: Has an idea but experimental design is unclear
|
||||
|
||||
- confused: Doesn''t understand what needs to be tested
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs help
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Encourage creative experimental thinking! If they propose recombining colors, that''s
|
||||
|
||||
exactly what Newton did. If they have other ideas, evaluate if they would actually
|
||||
|
||||
distinguish between the two hypotheses.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- excellent_design
|
||||
- creative_approach
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_design:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Brilliant experimental design! Explain how this is similar to what Newton actually did and praise their scientific thinking.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
experiments_designed: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
creative_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Interesting approach! Evaluate whether their experiment would actually distinguish between the two hypotheses. If yes, praise them. If not, guide them.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
experiments_designed: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking in the right direction. Ask: if the prism creates color, could you reverse the process? If light contains the colors, could you recombine them?'
|
||||
next_section_and_step: section_2:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- '**Hint:** Think about what would happen differently based on each explanation:'
|
||||
- '- If the PRISM creates color, could you get white light back from colored light?'
|
||||
- '- If WHITE LIGHT contains colors, could you recombine them?'
|
||||
next_section_and_step: section_2:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Take time to think creatively! How could you test whether colors come from the light or from the prism?
|
||||
next_section_and_step: section_2:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question and provide guidance on experimental design principles.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_2:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on designing an experiment about light and prisms.
|
||||
next_section_and_step: section_2:step_1
|
||||
- step_id: step_2
|
||||
title: Identifying Variables
|
||||
content_blocks:
|
||||
- '## Identifying Variables'
|
||||
- Great thinking! Newton did indeed use a second prism to recombine the colors back into white light.
|
||||
- ''
|
||||
- '**Understanding Variables:**'
|
||||
- 'In any experiment, we need to identify:'
|
||||
- '- **Independent variable:** What YOU change'
|
||||
- '- **Dependent variable:** What you MEASURE'
|
||||
- '- **Control variables:** What you keep THE SAME'
|
||||
- ''
|
||||
- '**Example scenario:**'
|
||||
- You want to test if plants grow faster with music.
|
||||
- ''
|
||||
- 'You set up:'
|
||||
- '- 10 plants with music'
|
||||
- '- 10 plants without music'
|
||||
- '- All plants get same water, light, soil, and temperature'
|
||||
- '- Measure growth after 2 weeks'
|
||||
question: Identify the independent variable, dependent variable, and control variables in this plant experiment.
|
||||
tokens_for_ai: 'Correct answers:
|
||||
|
||||
- Independent variable: Presence/absence of music (what you change)
|
||||
|
||||
- Dependent variable: Plant growth/height (what you measure)
|
||||
|
||||
- Control variables: Water, light, soil, temperature (what you keep the same)
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Correctly identifies all three types of variables
|
||||
|
||||
- partial_understanding: Gets 2 out of 3 correct
|
||||
|
||||
- confused: Mixes up independent and dependent
|
||||
|
||||
- limited_effort: Very brief or incomplete
|
||||
|
||||
- asking_clarifying_questions: Needs clarification
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they confuse independent and dependent, explain: independent is what the experimenter
|
||||
|
||||
controls/changes, dependent is what responds/changes as a result.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Perfect! You understand variables - a crucial concept in experimental design.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
controls_identified: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good start! Clarify which variables they got right and help with the others.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- '**Tip:** The INDEPENDENT variable is what the experimenter changes on purpose.'
|
||||
- The DEPENDENT variable is what you measure to see the effect.
|
||||
- CONTROL variables are kept the same so they don't interfere.
|
||||
next_section_and_step: section_2:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Try to identify each type: What are you changing? What are you measuring? What are you keeping the same?'
|
||||
next_section_and_step: section_2:step_2
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about variables clearly with examples.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_2:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on identifying the different types of variables in this experiment.
|
||||
next_section_and_step: section_2:step_2
|
||||
- section_id: section_3
|
||||
title: Avoiding Bias and Errors
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Recognizing Experimental Bias
|
||||
content_blocks:
|
||||
- '## Recognizing Experimental Bias'
|
||||
- Good scientists must watch out for bias and confounding factors!
|
||||
- ''
|
||||
- '**Scenario:**'
|
||||
- A pharmaceutical company tests a new headache medicine.
|
||||
- ''
|
||||
- '**Experimental setup:**'
|
||||
- '- Group A: 100 patients receive the new medicine'
|
||||
- '- Group B: 100 patients receive nothing'
|
||||
- '- Researchers record who reports headache relief'
|
||||
- ''
|
||||
- '**Results:**'
|
||||
- '- Group A: 80% report relief'
|
||||
- '- Group B: 30% report relief'
|
||||
- ''
|
||||
- The company concludes the medicine works!
|
||||
question: Is there a problem with this experimental design? What's missing or problematic?
|
||||
tokens_for_ai: 'Major problems:
|
||||
|
||||
- No placebo (Group B should get a fake pill, not nothing)
|
||||
|
||||
- Placebo effect not controlled for
|
||||
|
||||
- Patients know if they''re getting treatment (should be blind/double-blind)
|
||||
|
||||
- Researcher bias possible if they know who got real medicine
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- identified_placebo: Recognizes need for placebo control
|
||||
|
||||
- identified_blinding: Recognizes need for blind study
|
||||
|
||||
- partial_understanding: Sees something wrong but can''t articulate it clearly
|
||||
|
||||
- missed_bias: Doesn''t see the problem
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs explanation
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they identify placebo effect, excellent! If not, explain that people often feel
|
||||
|
||||
better just because they think they''re getting treatment. That''s why we need placebo
|
||||
|
||||
controls and blind studies.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- identified_placebo
|
||||
- identified_blinding
|
||||
- partial_understanding
|
||||
- missed_bias
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
identified_placebo:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! You identified the placebo effect. Explain why placebos are crucial in medical research.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
bias_identified: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
identified_blinding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Great catch! Explain how blinding prevents bias in both patients and researchers.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
bias_identified: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're sensing something's wrong. Guide them toward the placebo effect concept.
|
||||
next_section_and_step: section_3:step_1
|
||||
missed_bias:
|
||||
content_blocks:
|
||||
- '**Hint:** Think about the psychological effect of KNOWING you''re getting medicine.'
|
||||
- What if people feel better just because they believe they're being treated?
|
||||
next_section_and_step: section_3:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Think carefully: Is it fair to compare people who GET something to people who get NOTHING?'
|
||||
next_section_and_step: section_3:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about experimental design and bias.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_3:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze this medical experiment. Is the design fair and unbiased?
|
||||
next_section_and_step: section_3:step_1
|
||||
- step_id: step_2
|
||||
title: Scientific Integrity
|
||||
content_blocks:
|
||||
- '## Scientific Integrity'
|
||||
- Excellent work identifying bias!
|
||||
- ''
|
||||
- '**Key principles for good science:**'
|
||||
- ''
|
||||
- ✓ **Use controls** - Compare to a baseline or control group
|
||||
- ✓ **Use placebos** - Control for psychological effects
|
||||
- ✓ **Blind studies** - Subjects don't know if they got real treatment
|
||||
- ✓ **Double-blind** - Researchers also don't know (prevents their bias)
|
||||
- ✓ **Replicate** - Repeat experiments to confirm results
|
||||
- ✓ **Peer review** - Other scientists check your work
|
||||
- ✓ **Large sample sizes** - More data = more reliable
|
||||
- ✓ **Account for confounding variables** - What else might affect results?
|
||||
- ''
|
||||
- These principles help ensure that scientific findings are reliable and trustworthy.
|
||||
question: Why do you think it's important for other scientists to be able to replicate (repeat) an experiment? What purpose does replication serve in science?
|
||||
tokens_for_ai: 'Good answers mention:
|
||||
|
||||
- Verifying results weren''t due to chance
|
||||
|
||||
- Catching errors or fraud
|
||||
|
||||
- Building confidence in findings
|
||||
|
||||
- Testing if results hold in different conditions
|
||||
|
||||
- Science is self-correcting
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- insightful: Understands multiple purposes of replication
|
||||
|
||||
- correct_understanding: Gets the basic concept (verification)
|
||||
|
||||
- partial_understanding: General idea but incomplete
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Encourage their understanding of how science builds reliable knowledge through
|
||||
|
||||
replication and peer review. Connect it to why we can trust scientific consensus.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- insightful
|
||||
- correct_understanding
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
insightful:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent understanding of scientific process! You grasp why science is a self-correcting system.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
next_section_and_step: section_4:step_1
|
||||
correct_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! Replication is indeed crucial for verifying results. Expand on other benefits if they didn't mention them.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: section_4:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're on the right track. Explain how replication helps catch errors and builds confidence.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what happens if only ONE person does an experiment. How do we know if their result was accurate?
|
||||
next_section_and_step: section_3:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on why repeating experiments is important in science.
|
||||
next_section_and_step: section_3:step_2
|
||||
- section_id: section_4
|
||||
title: Reflection and Conclusion
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Congratulations!
|
||||
content_blocks:
|
||||
- '## Congratulations, Scientist! 🔬'
|
||||
- You've completed the Scientific Method Explorer!
|
||||
- ''
|
||||
- '**What you''ve learned:**'
|
||||
- ✓ The steps of the scientific method
|
||||
- ✓ How to form testable hypotheses
|
||||
- ✓ Experimental design principles
|
||||
- ✓ Identifying variables (independent, dependent, control)
|
||||
- ✓ The importance of controls and placebos
|
||||
- ✓ Recognizing bias in experiments
|
||||
- ✓ Why replication and peer review matter
|
||||
- ''
|
||||
- '**Famous scientists you studied:**'
|
||||
- '- Ignaz Semmelweis (germ theory and handwashing)'
|
||||
- '- Isaac Newton (nature of light)'
|
||||
- ''
|
||||
- '**Why this matters:**'
|
||||
- The scientific method is how we reliably discover truth about the natural world.
|
||||
- 'These principles apply whether you''re:'
|
||||
- '- Testing a new technology'
|
||||
- '- Debugging code (forming and testing hypotheses!)'
|
||||
- '- Evaluating health claims'
|
||||
- '- Understanding climate science'
|
||||
- '- Or pursuing any evidence-based inquiry'
|
||||
question: How might you apply scientific thinking in your own life or studies? Give an example of a question you could investigate using the scientific method.
|
||||
tokens_for_ai: 'This is a reflection question. Accept any thoughtful application of scientific method
|
||||
|
||||
to a real-world question or problem.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- excellent_application: Proposes a specific, testable question with clear methodology
|
||||
|
||||
- good_application: Identifies a reasonable application area
|
||||
|
||||
- basic_reflection: General but genuine reflection
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide personalized, encouraging feedback on their learning journey. Acknowledge their
|
||||
|
||||
application ideas. Encourage them to actually try investigating something scientifically.
|
||||
|
||||
Emphasize that scientific thinking is a powerful tool for understanding the world.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- excellent_application
|
||||
- good_application
|
||||
- basic_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_application:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Fantastic! Your example shows you truly understand how to apply the scientific method. Encourage them to actually investigate their question!
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
good_application:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Great thinking! Provide positive feedback and suggestions for how they could make their investigation more rigorous.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
basic_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for their reflection and summarize the key scientific principles they've learned.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their completion and encourage them to think scientifically in their daily life.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Think about how you could use scientific thinking in your own investigations. What question might you explore?
|
||||
next_section_and_step: section_4:step_1
|
||||
|
|
@ -1,895 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s engagement with world geography and cultural learning.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their curiosity about different regions
|
||||
|
||||
- Retention of geographical and cultural facts
|
||||
|
||||
- Respect and interest in cultural diversity
|
||||
|
||||
- Performance on geography questions
|
||||
|
||||
|
||||
Provide encouraging feedback and suggest areas of the world they might explore further.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome, World Explorer!
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome to World Geography
|
||||
content_blocks:
|
||||
- '# Welcome to World Geography & Cultural Awareness! 🌍'
|
||||
- Embark on a virtual journey around the world!
|
||||
- ''
|
||||
- '**In this adventure, you will:**'
|
||||
- '- Explore different continents and countries'
|
||||
- '- Learn fascinating cultural facts and traditions'
|
||||
- '- Discover historical connections between regions'
|
||||
- '- Test your geography knowledge'
|
||||
- '- Develop global awareness and appreciation for diversity'
|
||||
- ''
|
||||
- '**Your journey:**'
|
||||
- You'll choose which regions to explore, learn about each location, and answer questions to test your knowledge.
|
||||
- The more you explore, the more cultural insights you'll collect!
|
||||
- ''
|
||||
- Ready to explore our amazing planet?
|
||||
question: 'Which continent would you like to explore first? Choose: Africa, Asia, Europe, South America, or Oceania.'
|
||||
tokens_for_ai: 'Student is choosing their starting continent.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- africa: Chose Africa
|
||||
|
||||
- asia: Chose Asia
|
||||
|
||||
- europe: Chose Europe
|
||||
|
||||
- south_america: Chose South America
|
||||
|
||||
- oceania: Chose Oceania (Australia/Pacific)
|
||||
|
||||
- set_language: Setting language preference
|
||||
|
||||
- off_topic: Doesn''t choose a continent
|
||||
|
||||
'
|
||||
buckets:
|
||||
- africa
|
||||
- asia
|
||||
- europe
|
||||
- south_america
|
||||
- oceania
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
africa:
|
||||
content_blocks:
|
||||
- 🌍 Excellent choice! Let's explore the diverse continent of Africa!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
current_continent: Africa
|
||||
next_section_and_step: africa:step_1
|
||||
asia:
|
||||
content_blocks:
|
||||
- 🌏 Wonderful! Asia awaits - the world's largest and most populous continent!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
current_continent: Asia
|
||||
next_section_and_step: asia:step_1
|
||||
europe:
|
||||
content_blocks:
|
||||
- 🌍 Great! Let's discover the rich history and culture of Europe!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
current_continent: Europe
|
||||
next_section_and_step: europe:step_1
|
||||
south_america:
|
||||
content_blocks:
|
||||
- 🌎 Fantastic! South America's biodiversity and culture await!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
current_continent: South America
|
||||
next_section_and_step: south_america:step_1
|
||||
oceania:
|
||||
content_blocks:
|
||||
- 🌏 Awesome! Let's explore the islands and nations of Oceania!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
current_continent: Oceania
|
||||
next_section_and_step: oceania:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- 'Please choose a continent to explore: Africa, Asia, Europe, South America, or Oceania.'
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: africa
|
||||
title: Exploring Africa
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Welcome to Africa - Kenya
|
||||
content_blocks:
|
||||
- '## Welcome to Africa! 🦁'
|
||||
- Africa is the world's second-largest continent, home to 54 countries and over 1.3 billion people.
|
||||
- ''
|
||||
- '**Let''s visit Kenya!**'
|
||||
- ''
|
||||
- '**Geography:** Kenya is located in East Africa, bordered by the Indian Ocean.'
|
||||
- '**Capital:** Nairobi'
|
||||
- '**Famous for:** Wildlife safaris, the Great Rift Valley, and being home to the Maasai people'
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- Kenya is known for its incredible biodiversity. The annual wildebeest migration through the Maasai Mara is one of the world's most spectacular natural events!
|
||||
- ''
|
||||
- '**Language Note:**'
|
||||
- While English and Swahili are official languages, Kenya has over 60 indigenous languages!
|
||||
- In Swahili, 'Jambo' means 'Hello' and 'Karibu' means 'Welcome'.
|
||||
question: What is the capital city of Kenya?
|
||||
tokens_for_ai: 'The capital of Kenya is Nairobi (just mentioned in the content).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Nairobi
|
||||
|
||||
- close: Says a major Kenyan city but not the capital (like Mombasa)
|
||||
|
||||
- confused_region: Names a capital from a different African country
|
||||
|
||||
- limited_effort: Very brief or no real answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, praise them! If they guessed another city, gently correct and perhaps share
|
||||
|
||||
a fun fact about Nairobi.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- confused_region
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! Nairobi is indeed the capital. Share an interesting fact about Nairobi being one of Africa's major cities.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: africa:step_2
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: That's a major city in Kenya, but the capital is Nairobi! Share a fact about both cities.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: africa:step_2
|
||||
confused_region:
|
||||
content_blocks:
|
||||
- That's a capital of another African country! Kenya's capital is Nairobi.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: africa:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look back at the information about Kenya. Which city is listed as the capital?
|
||||
next_section_and_step: africa:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on learning about Kenya. What is its capital city?
|
||||
next_section_and_step: africa:step_1
|
||||
- step_id: step_2
|
||||
title: Choose Your Next Destination
|
||||
content_blocks:
|
||||
- '## Journey Continues...'
|
||||
- Excellent! You've learned about Kenya.
|
||||
- ''
|
||||
- '**From Kenya, you can explore:**'
|
||||
- '- **North to Egypt** - Ancient pyramids and the Nile River'
|
||||
- '- **West to Nigeria** - Africa''s most populous country, rich in culture and music'
|
||||
- '- **South to South Africa** - Diverse landscapes from savannas to mountains'
|
||||
- '- **Continue to a new continent** - Asia, Europe, South America, or Oceania'
|
||||
question: Where would you like to go next?
|
||||
tokens_for_ai: 'Student is choosing their next destination.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- egypt: North to Egypt
|
||||
|
||||
- nigeria: West to Nigeria
|
||||
|
||||
- south_africa: South to South Africa
|
||||
|
||||
- new_continent: Wants to explore a different continent
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- egypt
|
||||
- nigeria
|
||||
- south_africa
|
||||
- new_continent
|
||||
- off_topic
|
||||
transitions:
|
||||
egypt:
|
||||
content_blocks:
|
||||
- 🐪 Heading north to Egypt - land of pharaohs!
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: africa_egypt:step_1
|
||||
nigeria:
|
||||
content_blocks:
|
||||
- 🎵 Traveling west to Nigeria - birthplace of Afrobeat!
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: africa_nigeria:step_1
|
||||
south_africa:
|
||||
content_blocks:
|
||||
- 🦏 Heading south to South Africa - the Rainbow Nation!
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: africa_south:step_1
|
||||
new_continent:
|
||||
content_blocks:
|
||||
- Ready to explore a new continent! Great choice.
|
||||
next_section_and_step: choose_continent:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- 'Please choose your next destination: Egypt, Nigeria, South Africa, or a new continent.'
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: africa:step_2
|
||||
- section_id: africa_egypt
|
||||
title: Egypt
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Egypt - Land of Ancient Wonders
|
||||
content_blocks:
|
||||
- '## Egypt - Land of Ancient Wonders 🐪'
|
||||
- '**Geography:** Located in Northeast Africa, Egypt connects Africa to Asia via the Sinai Peninsula.'
|
||||
- '**Capital:** Cairo'
|
||||
- '**Famous for:** The Pyramids of Giza, the Sphinx, the Nile River (world''s longest river)'
|
||||
- ''
|
||||
- '**Historical Fact:**'
|
||||
- Ancient Egyptian civilization lasted over 3,000 years! They developed hieroglyphic writing, built massive monuments, and made advances in mathematics, medicine, and astronomy.
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- The Nile River has been central to Egyptian life for millennia. The ancient saying 'Egypt is the gift of the Nile' reflects how the river's annual flooding made agriculture possible in the desert.
|
||||
question: What is the world's longest river, which flows through Egypt?
|
||||
tokens_for_ai: 'The answer is the Nile River (mentioned multiple times above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Nile or Nile River
|
||||
|
||||
- confused: Names another famous long river (Amazon, Yangtze, Mississippi)
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, praise them! If they say Amazon (second longest), acknowledge it''s close but
|
||||
|
||||
the Nile is slightly longer.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! The Nile is indeed the world's longest river. Share a fascinating fact about its importance.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused:
|
||||
ai_feedback:
|
||||
tokens_for_ai: That's another long river! But the Nile is the world's longest. Explain the comparison between them.
|
||||
metadata_add:
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the information about Egypt. Which river is mentioned as the world's longest?
|
||||
next_section_and_step: africa_egypt:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on geography. What is the world's longest river?
|
||||
next_section_and_step: africa_egypt:step_1
|
||||
- section_id: africa_nigeria
|
||||
title: Nigeria
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Nigeria - Heart of West Africa
|
||||
content_blocks:
|
||||
- '## Nigeria - Heart of West Africa 🎵'
|
||||
- '**Geography:** Located in West Africa on the Gulf of Guinea'
|
||||
- '**Capital:** Abuja'
|
||||
- '**Famous for:** Being Africa''s most populous country (over 200 million people), Nollywood (film industry), Afrobeat music'
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- Nigeria is incredibly diverse with over 250 ethnic groups and 500+ languages! The largest groups are Hausa, Yoruba, and Igbo.
|
||||
- ''
|
||||
- '**Music Heritage:**'
|
||||
- Nigeria is the birthplace of Afrobeat, pioneered by Fela Kuti. Today, Nigerian artists are internationally renowned in genres from Afrobeats to hip-hop.
|
||||
question: Nigeria is famous for its film industry. What is it called?
|
||||
tokens_for_ai: 'The answer is Nollywood (mentioned above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Nollywood
|
||||
|
||||
- confused: Says Bollywood or Hollywood
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, share fun facts about Nollywood being one of the world''s largest film
|
||||
|
||||
industries by volume!
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! Nollywood is one of the world's largest film industries. Share impressive statistics about it.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused:
|
||||
ai_feedback:
|
||||
tokens_for_ai: That's a film industry, but Nigeria has its own! It's called Nollywood.
|
||||
metadata_add:
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Check the information about Nigeria. What is their film industry called? (Hint: it rhymes with Hollywood!)'
|
||||
next_section_and_step: africa_nigeria:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's learn about Nigerian culture. What is their film industry called?
|
||||
next_section_and_step: africa_nigeria:step_1
|
||||
- section_id: africa_south
|
||||
title: South Africa
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: South Africa - The Rainbow Nation
|
||||
content_blocks:
|
||||
- '## South Africa - The Rainbow Nation 🦏'
|
||||
- '**Geography:** Located at the southern tip of Africa'
|
||||
- '**Capitals:** THREE! Pretoria (executive), Cape Town (legislative), Bloemfontein (judicial)'
|
||||
- '**Famous for:** Diverse landscapes, wildlife (Big Five: lion, leopard, rhino, elephant, buffalo), and being called the ''Rainbow Nation'' for its multicultural diversity'
|
||||
- ''
|
||||
- '**Historical Fact:**'
|
||||
- Nelson Mandela led the struggle against apartheid and became South Africa's first Black president in 1994, helping to create a democratic, multicultural nation.
|
||||
- ''
|
||||
- '**Language Diversity:**'
|
||||
- South Africa has 11 official languages, including English, Afrikaans, Zulu, and Xhosa!
|
||||
question: How many official languages does South Africa have?
|
||||
tokens_for_ai: 'The answer is 11 (mentioned above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says 11 or eleven
|
||||
|
||||
- close: Says a number between 8-15
|
||||
|
||||
- confused: Says 1, 2, or 3
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct or close, praise their attention! Share how this linguistic diversity reflects
|
||||
|
||||
the country''s multicultural heritage.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Exactly right - 11 official languages! Explain what this reveals about South African diversity.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Very close! South Africa has exactly 11 official languages. Explain why this is significant.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- Actually, South Africa is remarkably diverse! It has 11 official languages.
|
||||
metadata_add:
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the language diversity section. How many official languages are mentioned?
|
||||
next_section_and_step: africa_south:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on South African culture. How many official languages does the country have?
|
||||
next_section_and_step: africa_south:step_1
|
||||
- section_id: asia
|
||||
title: Exploring Asia
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Welcome to Asia - Japan
|
||||
content_blocks:
|
||||
- '## Welcome to Asia! 🏯'
|
||||
- Asia is the world's largest continent, covering 30% of Earth's land area and home to 60% of the world's population!
|
||||
- ''
|
||||
- '**Let''s visit Japan!**'
|
||||
- ''
|
||||
- '**Geography:** An island nation in East Asia, consisting of 4 main islands and thousands of smaller ones'
|
||||
- '**Capital:** Tokyo'
|
||||
- '**Famous for:** Technology, anime/manga, cherry blossoms, ancient temples, and a unique blend of tradition and modernity'
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- Japan has a deep tradition of respect and harmony. The concept of 'wa' (和) emphasizes peace and balance in relationships.
|
||||
- Bowing is a traditional greeting showing respect!
|
||||
- ''
|
||||
- '**Interesting Note:**'
|
||||
- 'Japan has more than 6,800 islands, though most people live on the four largest: Honshu, Hokkaido, Kyushu, and Shikoku.'
|
||||
question: What is the capital of Japan?
|
||||
tokens_for_ai: 'The answer is Tokyo (mentioned above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Tokyo
|
||||
|
||||
- close: Names another major Japanese city (Osaka, Kyoto)
|
||||
|
||||
- confused_region: Names a capital from another Asian country
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, share a fact about Tokyo being one of the world''s largest metropolitan areas!
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- confused_region
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! Tokyo is the capital and one of the world's largest cities. Share a fascinating fact about it.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: That's an important Japanese city! But the capital is Tokyo. Explain the historical significance of Kyoto if they mentioned it.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused_region:
|
||||
content_blocks:
|
||||
- That's a capital of another Asian country! Japan's capital is Tokyo.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the information about Japan. Which city is the capital?
|
||||
next_section_and_step: asia:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's learn about Japan. What is its capital city?
|
||||
next_section_and_step: asia:step_1
|
||||
- section_id: europe
|
||||
title: Exploring Europe
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Welcome to Europe - Italy
|
||||
content_blocks:
|
||||
- '## Welcome to Europe! 🏰'
|
||||
- Europe may be small in size, but it's mighty in history, culture, and diversity!
|
||||
- ''
|
||||
- '**Let''s visit Italy!**'
|
||||
- ''
|
||||
- '**Geography:** A boot-shaped peninsula in Southern Europe, extending into the Mediterranean Sea'
|
||||
- '**Capital:** Rome'
|
||||
- '**Famous for:** Ancient Roman history, Renaissance art, delicious cuisine (pizza, pasta!), and beautiful architecture'
|
||||
- ''
|
||||
- '**Historical Fact:**'
|
||||
- Rome was the heart of the Roman Empire, which at its height controlled most of Europe, North Africa, and the Middle East. The saying 'All roads lead to Rome' comes from the extensive Roman road network!
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- Italy is home to more UNESCO World Heritage Sites than any other country - 58 sites including the Colosseum, Venice, and Pompeii!
|
||||
question: What is the capital of Italy, which was also the center of the ancient Roman Empire?
|
||||
tokens_for_ai: 'The answer is Rome (mentioned multiple times above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Rome
|
||||
|
||||
- close: Names another major Italian city (Venice, Milan, Florence)
|
||||
|
||||
- confused_region: Names a capital from another European country
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, share excitement about Rome''s incredible history spanning over 2,500 years!
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- confused_region
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! Rome - the Eternal City - has over 2,500 years of history. Share a fascinating fact about it.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: That's a beautiful Italian city! But the capital is Rome. Share a fact about the city they mentioned if historically significant.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused_region:
|
||||
content_blocks:
|
||||
- That's a European capital, but Italy's capital is Rome!
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the information about Italy. Which city is mentioned as both the capital AND the center of the ancient Roman Empire?
|
||||
next_section_and_step: europe:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's learn about Italy. What is its capital city?
|
||||
next_section_and_step: europe:step_1
|
||||
- section_id: south_america
|
||||
title: Exploring South America
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Welcome to South America - Brazil
|
||||
content_blocks:
|
||||
- '## Welcome to South America! 🦜'
|
||||
- Home to the Amazon rainforest, the Andes mountains, and incredibly rich biodiversity!
|
||||
- ''
|
||||
- '**Let''s visit Brazil!**'
|
||||
- ''
|
||||
- '**Geography:** The largest country in South America, covering nearly half the continent'
|
||||
- '**Capital:** Brasília (planned and built in the 1960s)'
|
||||
- '**Famous for:** Amazon rainforest, carnival celebrations, football (soccer), and diverse ecosystems from rainforests to beaches'
|
||||
- ''
|
||||
- '**Environmental Fact:**'
|
||||
- The Amazon rainforest, which covers much of Brazil, is sometimes called the 'lungs of the Earth' because it produces about 20% of the world's oxygen!
|
||||
- ''
|
||||
- '**Cultural Fact:**'
|
||||
- Brazil is the only Portuguese-speaking country in South America (most others speak Spanish). Brazilian Portuguese has its own unique accent and expressions!
|
||||
question: What language is primarily spoken in Brazil?
|
||||
tokens_for_ai: 'The answer is Portuguese (mentioned above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Portuguese
|
||||
|
||||
- confused: Says Spanish (common misconception)
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they say Spanish, gently correct and explain this is a common misconception - Brazil
|
||||
|
||||
was colonized by Portugal, not Spain! If correct, praise them for knowing this fact.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! Many people think Spanish, but Brazil speaks Portuguese due to Portuguese colonization. Share why this is unique in South America.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Common misconception! Unlike most of South America, Brazil speaks Portuguese, not Spanish. Explain the historical reason.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the cultural fact section. Which language does Brazil speak?
|
||||
next_section_and_step: south_america:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's learn about Brazil. What language is primarily spoken there?
|
||||
next_section_and_step: south_america:step_1
|
||||
- section_id: oceania
|
||||
title: Exploring Oceania
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Welcome to Oceania - Australia
|
||||
content_blocks:
|
||||
- '## Welcome to Oceania! 🏝️'
|
||||
- A region of islands and nations in the Pacific Ocean!
|
||||
- ''
|
||||
- '**Let''s visit Australia!**'
|
||||
- ''
|
||||
- '**Geography:** The world''s smallest continent but largest island, located between the Indian and Pacific Oceans'
|
||||
- '**Capital:** Canberra'
|
||||
- '**Famous for:** Unique wildlife (kangaroos, koalas, platypuses), the Great Barrier Reef, the Outback, and indigenous Aboriginal culture spanning 65,000+ years'
|
||||
- ''
|
||||
- '**Indigenous Heritage:**'
|
||||
- Aboriginal Australians have the longest continuous culture on Earth - over 65,000 years! They have deep knowledge of the land, sophisticated art traditions, and hundreds of distinct languages.
|
||||
- ''
|
||||
- '**Wildlife Fact:**'
|
||||
- Australia has more unique species than anywhere else! About 80% of its plants, mammals, and reptiles are found nowhere else on Earth.
|
||||
question: What is the world's largest coral reef system, located off the coast of Australia?
|
||||
tokens_for_ai: 'The answer is the Great Barrier Reef (mentioned above).
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct: Says Great Barrier Reef or just Barrier Reef
|
||||
|
||||
- close: Mentions coral reef but not the specific name
|
||||
|
||||
- confused: Names another natural wonder in Australia
|
||||
|
||||
- limited_effort: Very brief or no answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If correct, share facts about it being visible from space and home to thousands of species!
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Correct! The Great Barrier Reef is the world's largest coral reef system and can even be seen from space! Share conservation importance.
|
||||
metadata_add:
|
||||
quiz_score: n+1
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're thinking of the right feature! It's called the Great Barrier Reef. Share impressive facts about it.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
cultural_facts_learned: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- That's an Australian feature, but we're looking for the coral reef! It's the Great Barrier Reef.
|
||||
metadata_add:
|
||||
countries_visited: n+1
|
||||
next_section_and_step: choose_continent:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Look at the information about Australia. What coral reef system is mentioned?
|
||||
next_section_and_step: oceania:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's learn about Australia. What is the famous coral reef system off its coast?
|
||||
next_section_and_step: oceania:step_1
|
||||
- section_id: choose_continent
|
||||
title: Continue Your Journey
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Choose Next Continent
|
||||
content_blocks:
|
||||
- '## Your World Journey Continues! ✈️'
|
||||
- Great exploring! You're building global knowledge.
|
||||
- ''
|
||||
- '**What would you like to do next?**'
|
||||
- '- Explore another continent (type: Africa, Asia, Europe, South America, or Oceania)'
|
||||
- '- Finish your journey and see what you''ve learned (type: finish)'
|
||||
question: Continue exploring or finish your journey?
|
||||
tokens_for_ai: 'Student chooses to continue or finish.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- africa: Wants to explore Africa
|
||||
|
||||
- asia: Wants to explore Asia
|
||||
|
||||
- europe: Wants to explore Europe
|
||||
|
||||
- south_america: Wants to explore South America
|
||||
|
||||
- oceania: Wants to explore Oceania
|
||||
|
||||
- finish: Ready to finish
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- africa
|
||||
- asia
|
||||
- europe
|
||||
- south_america
|
||||
- oceania
|
||||
- finish
|
||||
- off_topic
|
||||
transitions:
|
||||
africa:
|
||||
content_blocks:
|
||||
- 🌍 Heading to Africa!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
next_section_and_step: africa:step_1
|
||||
asia:
|
||||
content_blocks:
|
||||
- 🌏 Off to Asia!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
next_section_and_step: asia:step_1
|
||||
europe:
|
||||
content_blocks:
|
||||
- 🌍 Traveling to Europe!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
next_section_and_step: europe:step_1
|
||||
south_america:
|
||||
content_blocks:
|
||||
- 🌎 Journey to South America!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
next_section_and_step: south_america:step_1
|
||||
oceania:
|
||||
content_blocks:
|
||||
- 🌏 Exploring Oceania!
|
||||
metadata_add:
|
||||
continents_visited: n+1
|
||||
next_section_and_step: oceania:step_1
|
||||
finish:
|
||||
content_blocks:
|
||||
- 🌍 Wonderful! Let's reflect on your global journey.
|
||||
next_section_and_step: conclusion:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Choose a continent to explore (Africa, Asia, Europe, South America, Oceania) or type 'finish' to complete your journey.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: choose_continent:step_1
|
||||
- section_id: conclusion
|
||||
title: Journey Complete!
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Congratulations!
|
||||
content_blocks:
|
||||
- '## Congratulations, World Explorer! 🌍🌎🌏'
|
||||
- You've completed your global geography journey!
|
||||
- ''
|
||||
- '**Why geography and cultural awareness matter:**'
|
||||
- '- Helps us understand global events and connections'
|
||||
- '- Builds respect and appreciation for diversity'
|
||||
- '- Reveals how geography shapes culture, history, and daily life'
|
||||
- '- Prepares us to be global citizens in an interconnected world'
|
||||
- ''
|
||||
- '**Remember:**'
|
||||
- Every region has unique beauty, wisdom, and contributions to humanity.
|
||||
- Learning about the world helps us see both our differences and our common humanity.
|
||||
question: What was the most interesting cultural fact or place you learned about? What would you like to explore more deeply?
|
||||
tokens_for_ai: 'This is a reflection question. Accept any thoughtful response about their learning.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- thoughtful_reflection: Specific insights about what they learned
|
||||
|
||||
- brief_reflection: Short but genuine
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide personalized feedback based on their journey. Acknowledge the places they visited
|
||||
|
||||
(from metadata) and encourage continued exploration of world cultures.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- thoughtful_reflection
|
||||
- brief_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Provide thoughtful, personalized feedback about their learning journey. Suggest resources for further exploration of the topics that interested them most.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
brief_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their learning and encourage them to continue exploring world geography and cultures.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for their participation and summarize key geography and cultural facts they encountered.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's reflect on your journey. What did you find most interesting about the places you visited?
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,726 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s understanding of environmental science and sustainability.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their grasp of ecosystem connections and interdependencies
|
||||
|
||||
- Understanding of environmental impacts
|
||||
|
||||
- Ability to think about tradeoffs and systems thinking
|
||||
|
||||
- Engagement with sustainability concepts
|
||||
|
||||
- Quality of their decision-making and reasoning
|
||||
|
||||
|
||||
Provide encouraging feedback and suggestions for how they can apply sustainable thinking in their own lives.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Environmental Consulting
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome Environmental Consultant
|
||||
content_blocks:
|
||||
- '# Environmental Science & Sustainability 🌱'
|
||||
- Welcome, Environmental Consultant!
|
||||
- ''
|
||||
- You've been hired to help redesign River City to be more sustainable and environmentally friendly.
|
||||
- ''
|
||||
- '**Your mission:**'
|
||||
- Make decisions that balance environmental protection, economic needs, and quality of life.
|
||||
- ''
|
||||
- '**You''ll learn about:**'
|
||||
- '- Ecosystem interdependencies'
|
||||
- '- Carbon footprint and climate impact'
|
||||
- '- Renewable vs non-renewable energy'
|
||||
- '- Sustainable urban planning'
|
||||
- '- Biodiversity and habitat protection'
|
||||
- '- Systems thinking and tradeoffs'
|
||||
- ''
|
||||
- '**How it works:**'
|
||||
- You'll face real-world environmental challenges. Each decision affects the city's Environmental Health Score.
|
||||
- ''
|
||||
- Think carefully about both immediate and long-term consequences!
|
||||
question: Are you ready to create a more sustainable River City?
|
||||
tokens_for_ai: 'Student is expressing readiness.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- ready: Positive, ready to begin
|
||||
|
||||
- set_language: Setting language preference
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- Excellent! Let's start with your first environmental challenge.
|
||||
metadata_add:
|
||||
environmental_score: '50'
|
||||
decisions_made: '0'
|
||||
next_section_and_step: section_1:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's get started helping River City become more sustainable! Are you ready?
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: section_1
|
||||
title: Transportation Challenge
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Transportation Infrastructure
|
||||
content_blocks:
|
||||
- '## Challenge 1: Transportation Infrastructure 🚗🚌'
|
||||
- '**The Situation:**'
|
||||
- 'River City has severe traffic congestion. Most residents drive personal cars, creating:'
|
||||
- '- High carbon emissions'
|
||||
- '- Air pollution affecting public health'
|
||||
- '- Traffic jams wasting time and fuel'
|
||||
- ''
|
||||
- The city council has budget for ONE major transportation initiative.
|
||||
- ''
|
||||
- '**Your options:**'
|
||||
- '**A) Build more highways** - Reduce traffic jams, support car culture'
|
||||
- '**B) Expand public transit** - Buses and light rail, less convenient than cars but lower emissions per person'
|
||||
- '**C) Create bike lanes and pedestrian zones** - Healthiest and greenest option, but only works for shorter distances'
|
||||
- '**D) Mixed approach** - Smaller improvements to all three, but none will be as effective'
|
||||
question: Which transportation approach do you recommend? Explain your reasoning considering environmental impact, practicality, and long-term effects.
|
||||
tokens_for_ai: 'Evaluate their choice and reasoning.
|
||||
|
||||
|
||||
Sustainable choices in order: C (best), B (good), D (mixed), A (worst for environment)
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- sustainable_choice: Chooses B or C with environmental reasoning
|
||||
|
||||
- mixed_thinking: Chooses D with awareness of tradeoffs
|
||||
|
||||
- unsustainable: Chooses A (highways)
|
||||
|
||||
- thoughtful_tradeoff: Any choice with sophisticated understanding of tradeoffs
|
||||
|
||||
- limited_effort: Very brief or no reasoning
|
||||
|
||||
- asking_clarifying_questions: Needs more information
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide feedback on their environmental reasoning. If they chose highways, explain the
|
||||
|
||||
concept of "induced demand" - more highways lead to more driving. If they chose sustainable
|
||||
|
||||
options, praise their thinking and explain the benefits. Acknowledge legitimate concerns
|
||||
|
||||
about practicality and economic impacts.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- sustainable_choice
|
||||
- mixed_thinking
|
||||
- unsustainable
|
||||
- thoughtful_tradeoff
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
sustainable_choice:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent environmental thinking! Explain the positive impacts of their choice on emissions, health, and urban livability.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
carbon_reduced: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
mixed_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: A balanced approach can work! Discuss the tradeoffs and how to maximize environmental benefit within the mixed approach.
|
||||
metadata_add:
|
||||
environmental_score: n+5
|
||||
carbon_reduced: medium
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
unsustainable:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Explain 'induced demand' - more highways lead to more driving and sprawl. Suggest how public transit or bike infrastructure could address congestion more sustainably.
|
||||
metadata_add:
|
||||
environmental_score: n-5
|
||||
carbon_reduced: none
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
thoughtful_tradeoff:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're thinking systemically about the tradeoffs! Validate their sophisticated reasoning and provide additional context.
|
||||
metadata_add:
|
||||
environmental_score: n+7
|
||||
carbon_reduced: medium
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Please think more deeply about the environmental and practical implications of each option. What are the long-term effects?
|
||||
next_section_and_step: section_1:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question helpfully, providing information about emissions, costs, or practicality as requested.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_1:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the transportation challenge. Which option do you recommend and why?
|
||||
next_section_and_step: section_1:step_1
|
||||
- section_id: section_2
|
||||
title: Energy Challenge
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Energy Infrastructure
|
||||
content_blocks:
|
||||
- '## Challenge 2: Energy Infrastructure ⚡🌞'
|
||||
- '**The Situation:**'
|
||||
- 'River City''s power currently comes from:'
|
||||
- '- 70% coal (cheap but high carbon emissions and air pollution)'
|
||||
- '- 20% natural gas (cleaner than coal but still fossil fuel)'
|
||||
- '- 10% renewable (solar and wind)'
|
||||
- ''
|
||||
- The city wants to transition to cleaner energy. Budget allows for ONE major initiative.
|
||||
- ''
|
||||
- '**Your options:**'
|
||||
- '**A) Build large solar farm** - Clean energy, works great in sunny weather, needs battery storage for nighttime'
|
||||
- '**B) Invest in wind turbines** - Clean energy, works day and night if windy, some people find them unsightly'
|
||||
- '**C) Upgrade to natural gas** - Cleaner than coal, much lower cost than renewables, but still emits CO2'
|
||||
- '**D) Energy efficiency program** - Help residents insulate homes, use LED lights, efficient appliances - reduces total energy needed'
|
||||
question: Which energy strategy do you recommend? Consider climate impact, reliability, and cost.
|
||||
tokens_for_ai: 'Evaluate their choice and reasoning.
|
||||
|
||||
|
||||
Sustainability ranking: A or B (excellent), D (good), C (poor - still fossil fuel)
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- renewable_choice: Chooses A or B with climate reasoning
|
||||
|
||||
- efficiency_focus: Chooses D understanding that reducing demand is also sustainable
|
||||
|
||||
- transitional_thinking: Chooses C as a "bridge" fuel
|
||||
|
||||
- systems_thinking: Shows understanding of energy grid complexity
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs more info
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Discuss their reasoning. If they chose renewables, explain benefits and acknowledge
|
||||
|
||||
intermittency challenges. If they chose efficiency, praise reducing demand. If natural
|
||||
|
||||
gas, acknowledge it''s cleaner than coal but emphasize it''s still fossil fuel and won''t
|
||||
|
||||
meet long-term climate goals.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- renewable_choice
|
||||
- efficiency_focus
|
||||
- transitional_thinking
|
||||
- systems_thinking
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
renewable_choice:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent climate-conscious choice! Explain the long-term benefits of renewable energy for climate and air quality.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
carbon_reduced: high
|
||||
renewable_energy: 'true'
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
efficiency_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Smart thinking! Reducing energy demand is one of the most cost-effective climate solutions. Explain how efficiency complements renewable energy.
|
||||
metadata_add:
|
||||
environmental_score: n+8
|
||||
carbon_reduced: medium-high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
transitional_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Natural gas is cleaner than coal, but it's still a fossil fuel. Discuss the difference between a transitional step and a long-term solution for climate goals.
|
||||
metadata_add:
|
||||
environmental_score: n+3
|
||||
carbon_reduced: low
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
systems_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent systems thinking! Validate their sophisticated understanding and provide additional context on grid management.
|
||||
metadata_add:
|
||||
environmental_score: n+9
|
||||
carbon_reduced: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Please provide more reasoning about environmental impact and long-term sustainability. What are the climate implications?
|
||||
next_section_and_step: section_2:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about renewable energy, costs, or technical details.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_2:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the energy challenge. Which energy strategy would you recommend?
|
||||
next_section_and_step: section_2:step_1
|
||||
- section_id: section_3
|
||||
title: Land Use Challenge
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Green Space vs Development
|
||||
content_blocks:
|
||||
- '## Challenge 3: Green Space vs Development 🌳🏢'
|
||||
- '**The Situation:**'
|
||||
- River City has a 50-acre plot of undeveloped land with mature forest and a wetland.
|
||||
- ''
|
||||
- '**Why the forest and wetland matter:**'
|
||||
- '- Trees absorb CO2 (carbon sink)'
|
||||
- '- Wetlands filter water and prevent flooding'
|
||||
- '- Habitat for dozens of bird species, amphibians, and small mammals'
|
||||
- '- Cool air and reduce urban heat island effect'
|
||||
- ''
|
||||
- The city faces pressure to develop this land.
|
||||
- ''
|
||||
- '**Your options:**'
|
||||
- '**A) Preserve as nature reserve** - Maximum environmental benefit, provides green space for residents, but no economic development'
|
||||
- '**B) Build affordable housing** - Addresses housing shortage, but removes habitat and green benefits'
|
||||
- '**C) Mixed-use development** - Preserve 30 acres as park, develop 20 acres with green building standards'
|
||||
- '**D) Commercial development** - Shopping center, brings jobs and tax revenue, full removal of natural area'
|
||||
question: What do you recommend for this land? Consider biodiversity, climate impact, and community needs.
|
||||
tokens_for_ai: 'Evaluate their reasoning about balancing conservation and development.
|
||||
|
||||
|
||||
Sustainability ranking: A (best for environment), C (good compromise), B (mixed), D (worst)
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- conservation_priority: Chooses A with ecological reasoning
|
||||
|
||||
- balanced_approach: Chooses C recognizing need to balance multiple goals
|
||||
|
||||
- housing_priority: Chooses B emphasizing social needs
|
||||
|
||||
- development_focus: Chooses D
|
||||
|
||||
- sophisticated_tradeoff: Any choice with nuanced understanding of competing values
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs more info
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Discuss ecosystem services the forest provides. If they chose preservation, explain the
|
||||
|
||||
value of biodiversity and carbon sequestration. If mixed-use, validate the tradeoff thinking.
|
||||
|
||||
If development, discuss the irreversibility of habitat loss and the concept of ecosystem services.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- conservation_priority
|
||||
- balanced_approach
|
||||
- housing_priority
|
||||
- development_focus
|
||||
- sophisticated_tradeoff
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
conservation_priority:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Strong environmental reasoning! Explain the long-term value of ecosystem services and urban green space.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
biodiversity_protected: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
balanced_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good systems thinking! You're balancing environmental protection with community needs. Discuss how to maximize environmental benefit in the developed portion.
|
||||
metadata_add:
|
||||
environmental_score: n+7
|
||||
biodiversity_protected: medium
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
housing_priority:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Housing is indeed important! Explore whether there are alternative sites for housing that wouldn't destroy irreplaceable habitat. Discuss the value of ecosystem services.
|
||||
metadata_add:
|
||||
environmental_score: n+2
|
||||
biodiversity_protected: low
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
development_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Commercial development provides economic benefits, but at the cost of irreplaceable ecosystem services. Discuss what''s lost: carbon storage, water filtration, biodiversity, flood control.'
|
||||
metadata_add:
|
||||
environmental_score: n-3
|
||||
biodiversity_protected: none
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
sophisticated_tradeoff:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent analysis of competing values! Validate their nuanced thinking about ecology, economics, and social needs.
|
||||
metadata_add:
|
||||
environmental_score: n+8
|
||||
biodiversity_protected: medium-high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what would be permanently lost if the natural area is developed. What ecosystem services does it provide?
|
||||
next_section_and_step: section_3:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about ecosystem services, biodiversity, or development alternatives.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_3:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the land use decision. What would you recommend for the 50-acre natural area?
|
||||
next_section_and_step: section_3:step_1
|
||||
- section_id: section_4
|
||||
title: Waste & Circular Economy
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Waste Management
|
||||
content_blocks:
|
||||
- '## Challenge 4: Waste Management ♻️'
|
||||
- '**The Situation:**'
|
||||
- 'River City sends 80% of waste to landfills, where it:'
|
||||
- '- Takes up space (landfills filling up)'
|
||||
- '- Produces methane (a potent greenhouse gas)'
|
||||
- '- Wastes valuable materials'
|
||||
- ''
|
||||
- Only 20% is currently recycled.
|
||||
- ''
|
||||
- '**Understanding the circular economy:**'
|
||||
- Instead of 'take, make, dispose,' we can 'reduce, reuse, recycle' - keeping materials in use.
|
||||
- ''
|
||||
- '**Your options:**'
|
||||
- '**A) Mandatory recycling & composting** - Requires sorting, provides trucks, reduces landfill waste by ~50%'
|
||||
- '**B) Ban single-use plastics** - Eliminates major source of waste and ocean pollution'
|
||||
- '**C) Waste-to-energy incinerator** - Reduces landfill volume and generates electricity, but produces air emissions'
|
||||
- '**D) Producer responsibility laws** - Require manufacturers to take back and recycle their products'
|
||||
question: Which waste strategy would you implement? Consider environmental impact and systemic change.
|
||||
tokens_for_ai: 'Evaluate their understanding of circular economy and waste hierarchy.
|
||||
|
||||
|
||||
Sustainability ranking: A (good), B (good), D (excellent - addresses root cause), C (mixed - better than landfill but not ideal)
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- circular_economy: Chooses A or D with understanding of reuse/recycling
|
||||
|
||||
- pollution_prevention: Chooses B to eliminate plastic waste
|
||||
|
||||
- technical_solution: Chooses C (incineration)
|
||||
|
||||
- systems_thinking: Shows understanding of upstream vs downstream solutions
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs more info
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Discuss the waste hierarchy: reduce > reuse > recycle > recover energy > landfill.
|
||||
|
||||
If they chose producer responsibility, praise thinking about root causes. If recycling,
|
||||
|
||||
good but also mention reducing consumption. If incineration, discuss why it''s better
|
||||
|
||||
than landfill but not as good as preventing waste.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- circular_economy
|
||||
- pollution_prevention
|
||||
- technical_solution
|
||||
- systems_thinking
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
circular_economy:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! You understand circular economy principles. Explain how keeping materials in use reduces resource extraction and emissions.
|
||||
metadata_add:
|
||||
environmental_score: n+8
|
||||
waste_reduction: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_5:step_1
|
||||
pollution_prevention:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Great prevention thinking! Eliminating single-use plastics prevents pollution at the source. Discuss how this addresses ocean plastic crisis.
|
||||
metadata_add:
|
||||
environmental_score: n+9
|
||||
waste_reduction: high
|
||||
plastic_reduction: 'true'
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_5:step_1
|
||||
technical_solution:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Incineration is better than landfilling, but it's still treating symptoms rather than causes. Discuss the waste hierarchy and how prevention is better than end-of-pipe solutions.
|
||||
metadata_add:
|
||||
environmental_score: n+4
|
||||
waste_reduction: medium
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_5:step_1
|
||||
systems_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent systems thinking! You're looking at root causes rather than just managing waste. Validate their sophisticated approach.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
waste_reduction: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: section_5:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Think about the waste hierarchy: Is it better to prevent waste or manage it after it''s created?'
|
||||
next_section_and_step: section_4:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about waste management, recycling, or circular economy concepts.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_4:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on waste management. Which strategy would you recommend?
|
||||
next_section_and_step: section_4:step_1
|
||||
- section_id: section_5
|
||||
title: Food & Agriculture
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Sustainable Food Systems
|
||||
content_blocks:
|
||||
- '## Challenge 5: Sustainable Food Systems 🌾'
|
||||
- '**The Situation:**'
|
||||
- 'River City imports 90% of its food from distant farms, which:'
|
||||
- '- Requires energy for transportation (high carbon footprint)'
|
||||
- '- Makes city vulnerable to supply disruptions'
|
||||
- '- Disconnects residents from food sources'
|
||||
- ''
|
||||
- '**Environmental context:**'
|
||||
- Food systems account for ~25% of global greenhouse gas emissions
|
||||
- Agriculture uses 70% of freshwater globally
|
||||
- Industrial farming often depletes soil and harms biodiversity
|
||||
- ''
|
||||
- '**Your options:**'
|
||||
- '**A) Support local organic farms** - Lower transportation emissions, no pesticides, higher cost to consumers'
|
||||
- '**B) Urban farming program** - Rooftop gardens, community gardens, very local but limited scale'
|
||||
- '**C) Promote plant-based diets** - Meat production has 10-50x more emissions than plants, but culturally challenging'
|
||||
- '**D) Reduce food waste** - 30-40% of food is wasted; composting and redistribution can help'
|
||||
question: Which food sustainability strategy would you prioritize? Consider climate impact, feasibility, and food security.
|
||||
tokens_for_ai: 'Evaluate their understanding of food system environmental impacts.
|
||||
|
||||
|
||||
All options have merit! C (plant-based) has highest climate impact potential, D (waste reduction)
|
||||
|
||||
is high-impact and feasible, A and B support local food systems.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- climate_focused: Chooses C (plant-based) with emissions reasoning
|
||||
|
||||
- waste_reduction: Chooses D understanding the scale of food waste
|
||||
|
||||
- local_food: Chooses A or B for local benefits
|
||||
|
||||
- holistic_thinking: Shows understanding of multiple interconnected issues
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs more info
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'All choices have environmental merit! Validate their reasoning and provide context about
|
||||
|
||||
the environmental impacts they''re addressing. Discuss connections between food, climate,
|
||||
|
||||
biodiversity, and resource use.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- climate_focused
|
||||
- waste_reduction
|
||||
- local_food
|
||||
- holistic_thinking
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
climate_focused:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You've identified one of the highest-impact climate solutions! Explain why animal agriculture has such large emissions, while acknowledging cultural and practical challenges.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
carbon_reduced: very-high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
waste_reduction:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Excellent choice! Food waste is a massive but often overlooked problem. Explain the triple benefit: less production needed, less methane from landfills, food reaches hungry people.'
|
||||
metadata_add:
|
||||
environmental_score: n+9
|
||||
waste_reduction: high
|
||||
decisions_made: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
local_food:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good thinking about local food systems! Explain benefits for local economy, food security, and reducing transportation emissions. Note that production methods matter more than distance for some foods.
|
||||
metadata_add:
|
||||
environmental_score: n+7
|
||||
local_food: 'true'
|
||||
decisions_made: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
holistic_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent holistic understanding of food system sustainability! Validate their sophisticated systems thinking about multiple interconnected issues.
|
||||
metadata_add:
|
||||
environmental_score: n+10
|
||||
decisions_made: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Think about the full lifecycle of food: production, transportation, consumption, and waste. Where are the biggest environmental impacts?'
|
||||
next_section_and_step: section_5:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about food system environmental impacts, emissions, or sustainability strategies.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_5:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on food sustainability. Which strategy would you recommend?
|
||||
next_section_and_step: section_5:step_1
|
||||
- section_id: conclusion
|
||||
title: Sustainability Report
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Congratulations!
|
||||
content_blocks:
|
||||
- '## Congratulations, Environmental Consultant! 🌍'
|
||||
- You've completed your sustainability consulting project for River City!
|
||||
- ''
|
||||
- '**Key environmental concepts you explored:**'
|
||||
- ✓ Carbon footprint and climate impact
|
||||
- ✓ Renewable vs fossil fuel energy
|
||||
- ✓ Ecosystem services and biodiversity
|
||||
- ✓ Circular economy and waste hierarchy
|
||||
- ✓ Sustainable food systems
|
||||
- ✓ Systems thinking and tradeoffs
|
||||
- ''
|
||||
- '**Why sustainability matters:**'
|
||||
- 'Human wellbeing depends on healthy ecosystems - they provide:'
|
||||
- '- Clean air and water'
|
||||
- '- Climate regulation'
|
||||
- '- Food and materials'
|
||||
- '- Recreation and beauty'
|
||||
- ''
|
||||
- '**The challenge:**'
|
||||
- We must meet human needs while protecting the Earth's systems that support all life.
|
||||
- ''
|
||||
- '**What you learned:**'
|
||||
- '- Environmental problems are interconnected (systems thinking)'
|
||||
- '- Choices have both immediate and long-term consequences'
|
||||
- '- Prevention is better than treating symptoms'
|
||||
- '- We can balance environmental protection with human needs through thoughtful design'
|
||||
question: Reflecting on your decisions, what's one action you could take in your own life to reduce your environmental impact? What sustainability principle resonated most with you?
|
||||
tokens_for_ai: 'This is a reflection question. Accept any thoughtful response about personal application
|
||||
|
||||
of sustainability principles.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- specific_commitment: Identifies concrete action they plan to take
|
||||
|
||||
- thoughtful_reflection: Meaningful reflection on what they learned
|
||||
|
||||
- basic_reflection: Brief but genuine
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide personalized, encouraging feedback. Acknowledge the environmental decisions they
|
||||
|
||||
made throughout the activity. Emphasize that individual actions matter AND we need systemic
|
||||
|
||||
change. Encourage them to think about sustainability in their daily choices and to advocate
|
||||
|
||||
for environmental protection in their communities.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- specific_commitment
|
||||
- thoughtful_reflection
|
||||
- basic_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
specific_commitment:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Wonderful! Your specific commitment shows you're ready to apply what you learned. Encourage and support their action plan. Remind them that individual actions AND systemic advocacy both matter.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent reflection on sustainability principles! Provide encouragement and suggest ways to apply these concepts in daily life.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
basic_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for engaging with environmental challenges. Summarize key takeaways and encourage sustainable thinking.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their completion and encourage them to consider environmental impacts in their daily decisions.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's reflect on sustainability. What action could you take personally to reduce environmental impact?
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,827 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s development of media literacy skills.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their ability to identify credible vs unreliable sources
|
||||
|
||||
- Recognition of bias and propaganda techniques
|
||||
|
||||
- Understanding of fact-checking methods
|
||||
|
||||
- Critical thinking about information sources
|
||||
|
||||
- Application of media literacy principles
|
||||
|
||||
|
||||
Provide encouraging feedback and emphasize the importance of these skills in the digital age.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Media Literacy
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome to Media Literacy
|
||||
content_blocks:
|
||||
- '# Media Literacy & Information Evaluation 📰'
|
||||
- Welcome to the world of critical media consumption!
|
||||
- ''
|
||||
- In today's information-rich world, the ability to evaluate sources is essential.
|
||||
- ''
|
||||
- '**You''ll learn to:**'
|
||||
- '- Identify credible vs unreliable sources'
|
||||
- '- Recognize bias and propaganda techniques'
|
||||
- '- Fact-check claims effectively'
|
||||
- '- Detect emotional manipulation'
|
||||
- '- Understand how misinformation spreads'
|
||||
- '- Become a savvy information consumer'
|
||||
- ''
|
||||
- '**Why this matters:**'
|
||||
- Every day we're exposed to thousands of messages - news, ads, social media posts.
|
||||
- Some are accurate, some are biased, some are deliberately false.
|
||||
- Media literacy helps you navigate this landscape and make informed decisions.
|
||||
question: Ready to sharpen your information evaluation skills?
|
||||
tokens_for_ai: 'Student is expressing readiness.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- ready: Positive, ready to begin
|
||||
|
||||
- set_language: Setting language preference
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- Excellent! Let's start with the basics of source evaluation.
|
||||
metadata_add:
|
||||
misinformation_detected: '0'
|
||||
sources_verified: '0'
|
||||
next_section_and_step: section_1:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's begin developing your media literacy skills! Are you ready?
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: section_1
|
||||
title: Evaluating Sources
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Understanding Source Credibility
|
||||
content_blocks:
|
||||
- '## Understanding Source Credibility 🔍'
|
||||
- Not all information sources are equally reliable.
|
||||
- ''
|
||||
- '**Key questions to ask:**'
|
||||
- '- **Who created this?** (Author, organization)'
|
||||
- '- **What''s their expertise?** (Credentials, experience)'
|
||||
- '- **What''s their motive?** (Inform, persuade, sell, entertain?)'
|
||||
- '- **Is it verifiable?** (Can you check the facts?)'
|
||||
- '- **Who else reports this?** (Corroboration from other sources)'
|
||||
- ''
|
||||
- '**Example article to evaluate:**'
|
||||
- ''
|
||||
- '**Title:** ''Scientists Confirm Chocolate Cures All Diseases'''
|
||||
- '**Source:** ChocoLovers Blog'
|
||||
- '**Author:** No author listed'
|
||||
- '**Content:** Claims a new study proves chocolate cures cancer, diabetes, and heart disease. No study is named or linked. Article includes ads for chocolate products.'
|
||||
- '**No other news sources are reporting this story.**'
|
||||
question: Is this a credible source? Why or why not? What red flags do you notice?
|
||||
tokens_for_ai: 'This is clearly NOT credible. Red flags:
|
||||
|
||||
- Extraordinary claim ("cures ALL diseases")
|
||||
|
||||
- No author credentials
|
||||
|
||||
- No named study or link to research
|
||||
|
||||
- Biased source (ChocoLovers Blog)
|
||||
|
||||
- Financial motive (chocolate ads)
|
||||
|
||||
- No corroboration from other sources
|
||||
|
||||
- Lacks scientific plausibility
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correctly_identified: Recognizes this is not credible and identifies multiple red flags
|
||||
|
||||
- partially_correct: Sees it''s suspicious but misses some red flags
|
||||
|
||||
- missed_red_flags: Thinks it might be credible or only sees one red flag
|
||||
|
||||
- limited_effort: Very brief answer
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Praise identification of red flags! Walk through all the warning signs if they missed any.
|
||||
|
||||
Emphasize: extraordinary claims require extraordinary evidence, check for conflicts of
|
||||
|
||||
interest, and verify with multiple independent sources.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correctly_identified
|
||||
- partially_correct
|
||||
- missed_red_flags
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correctly_identified:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Excellent source evaluation! You identified the key red flags. Explain the principle: extraordinary claims require extraordinary evidence.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
misinformation_detected: n+1
|
||||
next_section_and_step: section_1:step_2
|
||||
partially_correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good critical thinking! You spotted some red flags. Point out any additional warning signs they missed.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
misinformation_detected: n+1
|
||||
next_section_and_step: section_1:step_2
|
||||
missed_red_flags:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Let''s examine this more carefully. Walk through the red flags: no named study, biased source, extraordinary claims, financial motive, no corroboration.'
|
||||
next_section_and_step: section_1:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Take time to analyze this carefully. Look at the source, the claims, the evidence provided, and whether other sources report this.
|
||||
next_section_and_step: section_1:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on evaluating this article. Is it credible? What red flags do you see?
|
||||
next_section_and_step: section_1:step_1
|
||||
- step_id: step_2
|
||||
title: Comparing Sources
|
||||
content_blocks:
|
||||
- '## Comparing Sources 📊'
|
||||
- Great work! Now let's compare different sources on the same topic.
|
||||
- ''
|
||||
- '**Topic: A new medical treatment**'
|
||||
- ''
|
||||
- '**Source A:**'
|
||||
- '- Journal of Medicine (peer-reviewed)'
|
||||
- '- Authors: Dr. Smith et al., university researchers'
|
||||
- '- Reports: ''Preliminary study of 200 patients shows 15% improvement in symptoms'''
|
||||
- '- Lists limitations and notes more research needed'
|
||||
- ''
|
||||
- '**Source B:**'
|
||||
- '- HealthMiracles.com'
|
||||
- '- No author listed'
|
||||
- '- Claims: ''Revolutionary cure helps 99% of patients!'''
|
||||
- '- Sells the treatment for $299'
|
||||
- '- No peer review or scientific citation'
|
||||
question: Which source is more credible, and why? What makes Source A different from Source B?
|
||||
tokens_for_ai: 'Source A is clearly more credible:
|
||||
|
||||
- Peer-reviewed journal
|
||||
|
||||
- Named researchers with credentials
|
||||
|
||||
- Modest, specific claims (15%, not 99%)
|
||||
|
||||
- Acknowledges limitations
|
||||
|
||||
- No financial conflict
|
||||
|
||||
|
||||
Source B has red flags:
|
||||
|
||||
- No author/credentials
|
||||
|
||||
- Extraordinary claims (99%)
|
||||
|
||||
- Selling the product (financial motive)
|
||||
|
||||
- No peer review
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correct_analysis: Identifies Source A as more credible with good reasoning
|
||||
|
||||
- partial_understanding: Gets the right answer but incomplete reasoning
|
||||
|
||||
- confused: Doesn''t clearly distinguish credibility
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they correctly identify A, praise their analysis! Explain peer review process and
|
||||
|
||||
why modest claims with limitations are actually MORE trustworthy than extraordinary
|
||||
|
||||
promises. Discuss financial conflicts of interest.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correct_analysis
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Excellent! You understand the hallmarks of credible scientific reporting: peer review, transparency about limitations, and absence of financial conflicts. Explain why modest claims are more trustworthy.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
sources_verified: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re on the right track! Expand on the specific factors that make Source A more trustworthy: peer review, credentialed authors, modest claims, acknowledged limitations.'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
sources_verified: n+1
|
||||
next_section_and_step: section_2:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- '**Key principle:** When evaluating sources, look for transparency, credentials, peer review, and absence of financial conflicts.'
|
||||
- Which source has these qualities?
|
||||
next_section_and_step: section_1:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Compare them systematically: Who wrote it? Is it peer-reviewed? Are the claims modest or extraordinary? Is someone selling something?'
|
||||
next_section_and_step: section_1:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's compare these two sources. Which is more credible and why?
|
||||
next_section_and_step: section_1:step_2
|
||||
- section_id: section_2
|
||||
title: Recognizing Bias
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Understanding Bias and Framing
|
||||
content_blocks:
|
||||
- '## Understanding Bias and Framing 📰'
|
||||
- All sources have some perspective, but recognizing bias helps you get fuller picture.
|
||||
- ''
|
||||
- '**Types of bias:**'
|
||||
- '- **Selection bias:** What facts are included or omitted?'
|
||||
- '- **Framing bias:** How is the story presented?'
|
||||
- '- **Word choice:** Loaded language vs neutral language'
|
||||
- ''
|
||||
- '**Example: Same event, two headlines:**'
|
||||
- ''
|
||||
- '**Headline A:** ''Protesters disrupt traffic, cause chaos downtown'''
|
||||
- '**Headline B:** ''Citizens march peacefully for voting rights'''
|
||||
- ''
|
||||
- '**Facts:** 5,000 people marched. Two streets closed for 3 hours. No violence or arrests. March was about voting rights legislation.'
|
||||
question: How does each headline frame the event differently? What does word choice reveal about each source's perspective?
|
||||
tokens_for_ai: 'Headline A uses negative framing: "disrupt," "chaos," focuses on inconvenience
|
||||
|
||||
Headline B uses positive framing: "peacefully," "citizens," emphasizes purpose
|
||||
|
||||
Both are describing the same factual event but with different emphasis and word choice.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- recognizes_bias: Identifies how each headline frames the story differently and discusses word choice
|
||||
|
||||
- partial_recognition: Sees some difference but doesn''t fully analyze framing
|
||||
|
||||
- missed_bias: Doesn''t recognize the bias or framing differences
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they recognize bias, excellent! Explain how both can be factually accurate yet
|
||||
|
||||
emphasize different aspects. Discuss how word choice ("disrupt" vs "march," "chaos" vs
|
||||
|
||||
"peaceful") shapes perception. Emphasize importance of reading multiple sources.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- recognizes_bias
|
||||
- partial_recognition
|
||||
- missed_bias
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
recognizes_bias:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent analysis of bias and framing! Explain how consuming news from multiple perspectives helps us understand the full picture.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
bias_identified: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
partial_recognition:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re seeing the difference! Dig deeper into the specific words used: ''disrupt'' vs ''march,'' ''chaos'' vs ''peaceful.'' How does this language shape our perception?'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
bias_identified: n+1
|
||||
next_section_and_step: section_2:step_2
|
||||
missed_bias:
|
||||
content_blocks:
|
||||
- 'Look closely at the word choices: ''disrupt'' vs ''march,'' ''chaos'' vs ''peaceful.'''
|
||||
- One headline emphasizes inconvenience, the other emphasizes the purpose and peaceful nature.
|
||||
- Same facts, different framing!
|
||||
next_section_and_step: section_2:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Compare the specific words used in each headline. What feeling does each create about the protest?
|
||||
next_section_and_step: section_2:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze these headlines. How does each one frame the protest differently?
|
||||
next_section_and_step: section_2:step_1
|
||||
- step_id: step_2
|
||||
title: Emotional Manipulation vs Facts
|
||||
content_blocks:
|
||||
- '## Emotional Manipulation vs Facts 💭'
|
||||
- Some content uses emotional triggers to bypass critical thinking.
|
||||
- ''
|
||||
- '**Propaganda techniques to watch for:**'
|
||||
- '- **Fear appeals:** ''If you don''t act now, disaster will happen!'''
|
||||
- '- **Bandwagon:** ''Everyone believes this, don''t be left out!'''
|
||||
- '- **Name-calling:** Attacking people rather than addressing arguments'
|
||||
- '- **Glittering generalities:** Vague positive language without substance'
|
||||
- '- **Appeals to emotion** over evidence'
|
||||
- ''
|
||||
- '**Example social media post:**'
|
||||
- ''
|
||||
- _'They're trying to hide the TRUTH from you! Don't be a sheep! Share this before it's deleted! Everyone who's smart knows this is happening! Wake up!'_
|
||||
- ''
|
||||
- The post contains no specific claims, sources, or verifiable facts.
|
||||
question: What propaganda techniques do you see in this post? What red flags indicate this is trying to manipulate rather than inform?
|
||||
tokens_for_ai: 'Propaganda techniques present:
|
||||
|
||||
- Fear/urgency ("before it''s deleted!")
|
||||
|
||||
- Bandwagon ("everyone who''s smart knows")
|
||||
|
||||
- Name-calling ("sheep")
|
||||
|
||||
- Emotional language ("TRUTH," "Wake up!")
|
||||
|
||||
- Vague claims with no specifics
|
||||
|
||||
- No sources or verifiable facts
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- identified_manipulation: Recognizes multiple propaganda techniques
|
||||
|
||||
- partial_recognition: Sees some manipulation tactics
|
||||
|
||||
- missed_manipulation: Doesn''t recognize the manipulative techniques
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Requests explanation
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they identify manipulation, excellent! Explain how these techniques are designed to
|
||||
|
||||
bypass critical thinking by triggering emotional responses. Contrast with informative
|
||||
|
||||
content that provides specific, verifiable claims.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- identified_manipulation
|
||||
- partial_recognition
|
||||
- missed_manipulation
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
identified_manipulation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! You spotted the emotional manipulation tactics. Explain how credible information provides specific, verifiable facts rather than emotional appeals.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
misinformation_detected: n+1
|
||||
bias_identified: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
partial_recognition:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Good start! Point out additional manipulation techniques they missed: fear/urgency, bandwagon, name-calling, vague claims without specifics.'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
misinformation_detected: n+1
|
||||
next_section_and_step: section_3:step_1
|
||||
missed_manipulation:
|
||||
content_blocks:
|
||||
- 'Look for emotional triggers: fear (''before it''s deleted''), peer pressure (''everyone who''s smart''), and name-calling (''sheep'').'
|
||||
- 'Notice: no specific facts, no sources, just emotional language designed to make you share without thinking.'
|
||||
next_section_and_step: section_2:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Analyze this post carefully. Is it providing facts and sources, or is it using emotions and pressure tactics?
|
||||
next_section_and_step: section_2:step_2
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about propaganda techniques and emotional manipulation.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: section_2:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze this social media post. What manipulation techniques do you notice?
|
||||
next_section_and_step: section_2:step_2
|
||||
- section_id: section_3
|
||||
title: Fact-Checking Methods
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: How to Fact-Check Claims
|
||||
content_blocks:
|
||||
- '## How to Fact-Check Claims ✓'
|
||||
- When you encounter a surprising claim, you can verify it!
|
||||
- ''
|
||||
- '**Fact-checking steps:**'
|
||||
- 1. **Check the original source** - Is the claim based on a real study/document?
|
||||
- 2. **Verify with fact-checking sites** - Snopes, FactCheck.org, PolitiFact, etc.
|
||||
- 3. **Look for corroboration** - Do credible news sources report this?
|
||||
- 4. **Check the date** - Is this old news being presented as new?
|
||||
- 5. **Reverse image search** - Are images real or manipulated?
|
||||
- 6. **Consider expertise** - Are experts in the field confirming this?
|
||||
- ''
|
||||
- '**Claim to evaluate:**'
|
||||
- ''
|
||||
- '_''Breaking: Government announces pizza is now a vegetable!''_'
|
||||
- ''
|
||||
- '**Quick research reveals:**'
|
||||
- '- This claim went viral in 2011'
|
||||
- '- What actually happened: Congress ruled that tomato paste on pizza counts toward vegetable requirements in school lunches'
|
||||
- '- Pizza itself was NOT declared a vegetable'
|
||||
- '- The claim misrepresents the actual policy'
|
||||
question: Is the viral claim accurate? What fact-checking steps revealed the truth?
|
||||
tokens_for_ai: 'The claim is INACCURATE/MISLEADING:
|
||||
|
||||
- Pizza was NOT declared a vegetable
|
||||
|
||||
- The actual policy was about tomato paste servings in school lunches
|
||||
|
||||
- The headline distorts what actually happened
|
||||
|
||||
- Checking the date reveals this is old news
|
||||
|
||||
|
||||
Fact-checking revealed: date checking, finding original source, understanding context
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- correctly_debunked: Identifies the claim as false/misleading and explains why
|
||||
|
||||
- partial_understanding: Sees something wrong but doesn''t fully explain
|
||||
|
||||
- fooled: Thinks the claim is accurate
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they debunk it, excellent! Explain how viral claims often distort real events to
|
||||
|
||||
create outrage. Discuss importance of checking dates and finding original sources.
|
||||
|
||||
This teaches the difference between "false" and "misleading."
|
||||
|
||||
'
|
||||
buckets:
|
||||
- correctly_debunked
|
||||
- partial_understanding
|
||||
- fooled
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
correctly_debunked:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent fact-checking! You identified that the viral claim distorts the real policy. Explain how misleading headlines often contain a grain of truth but misrepresent the reality.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
misinformation_detected: n+1
|
||||
sources_verified: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking critically! Clarify the distinction: the policy was about tomato paste portions, not declaring pizza a vegetable. The headline distorts reality.'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
sources_verified: n+1
|
||||
next_section_and_step: section_3:step_2
|
||||
fooled:
|
||||
content_blocks:
|
||||
- 'Look at what ACTUALLY happened versus the headline: The policy was about counting tomato paste as a vegetable serving, not declaring pizza itself a vegetable.'
|
||||
- The viral claim distorts the truth to create outrage!
|
||||
next_section_and_step: section_3:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Read the fact-check information carefully. What's the difference between the viral claim and what actually happened?
|
||||
next_section_and_step: section_3:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's fact-check this claim. Is it accurate based on the research provided?
|
||||
next_section_and_step: section_3:step_1
|
||||
- step_id: step_2
|
||||
title: Spotting Manipulated Media
|
||||
content_blocks:
|
||||
- '## Advanced: Spotting Deepfakes and Manipulated Media 🎭'
|
||||
- Technology now allows realistic fake images, videos, and audio.
|
||||
- ''
|
||||
- '**Warning signs of manipulated media:**'
|
||||
- '- Unusual lighting or shadows'
|
||||
- '- Mismatched details (watch, background elements)'
|
||||
- '- Unnatural movement or expressions (in video)'
|
||||
- '- Context seems wrong (location, date, people present)'
|
||||
- '- No other sources have this image/video'
|
||||
- ''
|
||||
- '**Best practice:** Use reverse image search (Google Images, TinEye) to find original source'
|
||||
- ''
|
||||
- '**Scenario:**'
|
||||
- You see a photo claiming to show a celebrity at a political rally yesterday.
|
||||
- ''
|
||||
- '**Reverse image search reveals:**'
|
||||
- The same photo appears in an article from 3 years ago at a completely different event.
|
||||
- The background has been digitally altered.
|
||||
question: What does this tell you about the photo? Why is reverse image search such a valuable tool?
|
||||
tokens_for_ai: 'The photo is FAKE/MANIPULATED:
|
||||
|
||||
- Original image is from a different event years ago
|
||||
|
||||
- Background has been altered
|
||||
|
||||
- This is misinformation
|
||||
|
||||
|
||||
Reverse image search helps:
|
||||
|
||||
- Find original context
|
||||
|
||||
- Detect recycled/manipulated images
|
||||
|
||||
- Verify when and where photo was actually taken
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- understood_manipulation: Recognizes the photo is fake and explains the value of reverse search
|
||||
|
||||
- partial_understanding: Gets general idea but incomplete
|
||||
|
||||
- confused: Doesn''t fully grasp the manipulation
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they understand, excellent! Explain how old images are often recycled to create
|
||||
|
||||
false narratives. Emphasize that reverse image search is a powerful tool anyone can
|
||||
|
||||
use to verify visual claims.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- understood_manipulation
|
||||
- partial_understanding
|
||||
- confused
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
understood_manipulation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Perfect! You understand how images can be manipulated and recycled. Explain how reverse image search helps verify visual claims and find original context.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
misinformation_detected: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good thinking! Emphasize that reverse image search reveals when images are recycled from different contexts or digitally altered.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: section_4:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- The photo is fake - it's from a different event years ago with an altered background.
|
||||
- Reverse image search helps you find where images really came from!
|
||||
next_section_and_step: section_3:step_2
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what it means that the same photo appears from years ago in a different context.
|
||||
next_section_and_step: section_3:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze this scenario. What does the reverse image search reveal?
|
||||
next_section_and_step: section_3:step_2
|
||||
- section_id: section_4
|
||||
title: Building Your Media Diet
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Creating a Healthy Information Diet
|
||||
content_blocks:
|
||||
- '## Creating a Healthy Information Diet 🧠'
|
||||
- You've learned to spot misinformation, bias, and manipulation!
|
||||
- ''
|
||||
- '**Now: Building good habits**'
|
||||
- ''
|
||||
- '**Principles for healthy media consumption:**'
|
||||
- ''
|
||||
- ✓ **Diverse sources** - Read multiple perspectives, not just sources you agree with
|
||||
- ✓ **Primary sources** - When possible, check original documents/studies, not just summaries
|
||||
- ✓ **Slow down** - Resist the urge to share immediately; verify first
|
||||
- ✓ **Check your emotions** - If content makes you very angry/scared, pause and fact-check
|
||||
- ✓ **Know the difference** - News, opinion, satire, and propaganda are different
|
||||
- ✓ **Digital hygiene** - Regularly audit your information sources
|
||||
- ''
|
||||
- '**Question:**'
|
||||
- You see a shocking headline that confirms something you already believe.
|
||||
- ''
|
||||
- '**What should you do BEFORE sharing it?**'
|
||||
question: What steps should you take before sharing a shocking claim, even if it confirms your beliefs?
|
||||
tokens_for_ai: 'Good practices before sharing:
|
||||
|
||||
- Check the source (is it credible?)
|
||||
|
||||
- Verify with fact-checking sites
|
||||
|
||||
- Look for corroboration from other sources
|
||||
|
||||
- Check if it''s satire
|
||||
|
||||
- Be extra skeptical of claims that confirm your biases (confirmation bias)
|
||||
|
||||
- Read beyond the headline
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- comprehensive_approach: Lists multiple verification steps
|
||||
|
||||
- basic_verification: Mentions checking source or fact-checking
|
||||
|
||||
- confirmation_bias_awareness: Recognizes need to be extra skeptical of agreeable claims
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they show verification thinking, excellent! Emphasize the importance of being
|
||||
|
||||
especially skeptical of claims we WANT to believe (confirmation bias). Discuss the
|
||||
|
||||
responsibility of sharing in the digital age - false information spreads faster than
|
||||
|
||||
corrections.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- comprehensive_approach
|
||||
- basic_verification
|
||||
- confirmation_bias_awareness
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
comprehensive_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent! You've internalized the verification process. Emphasize that sharing misinformation, even unintentionally, contributes to the problem.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
next_section_and_step: conclusion:step_1
|
||||
basic_verification:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Good instinct to verify! Expand on additional steps: check multiple sources, use fact-checking sites, be extra skeptical of claims you want to believe.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: conclusion:step_1
|
||||
confirmation_bias_awareness:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent self-awareness! Recognizing confirmation bias is crucial. We're all more likely to believe and share claims that confirm what we already think.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
next_section_and_step: conclusion:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Think about the verification steps you''ve learned: checking sources, fact-checking sites, looking for corroboration, being skeptical of claims you want to believe.'
|
||||
next_section_and_step: section_4:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's think about responsible information sharing. What should you do before sharing a claim?
|
||||
next_section_and_step: section_4:step_1
|
||||
- section_id: conclusion
|
||||
title: Media Literacy Graduate
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Congratulations!
|
||||
content_blocks:
|
||||
- '## Congratulations, Media Literacy Expert! 🎓'
|
||||
- You've developed critical skills for navigating the information landscape!
|
||||
- ''
|
||||
- '**What you''ve learned:**'
|
||||
- ✓ How to evaluate source credibility
|
||||
- ✓ Recognizing bias and framing
|
||||
- ✓ Identifying propaganda and emotional manipulation
|
||||
- ✓ Fact-checking techniques (including reverse image search)
|
||||
- ✓ Building a healthy media diet
|
||||
- ✓ Spotting misinformation before it spreads
|
||||
- ''
|
||||
- '**Why this matters in the digital age:**'
|
||||
- '- Information spreads faster than ever before'
|
||||
- '- Misinformation can influence elections, health decisions, and social trust'
|
||||
- '- Critical thinking is essential for democracy'
|
||||
- '- You have power AND responsibility as an information consumer and sharer'
|
||||
- ''
|
||||
- '**Remember:**'
|
||||
- _'The inability to distinguish fact from fiction is the defining challenge of our age.'_
|
||||
- ''
|
||||
- You now have the tools to meet this challenge.
|
||||
- ''
|
||||
- '**Your media literacy checklist:**'
|
||||
- '- Check the source'
|
||||
- '- Verify with multiple sources'
|
||||
- '- Watch for emotional manipulation'
|
||||
- '- Fact-check before sharing'
|
||||
- '- Consume diverse perspectives'
|
||||
- '- Stay curious and humble'
|
||||
question: How will you apply media literacy in your daily life? What's one specific habit you want to develop to be a more critical information consumer?
|
||||
tokens_for_ai: 'This is a reflection question about applying media literacy skills.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- specific_commitment: Identifies a concrete practice they''ll adopt
|
||||
|
||||
- thoughtful_reflection: Meaningful reflection on importance of media literacy
|
||||
|
||||
- basic_reflection: Brief but genuine
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide encouraging, personalized feedback. Emphasize that media literacy is a lifelong
|
||||
|
||||
practice, not a destination. Acknowledge the challenges of the information age and praise
|
||||
|
||||
their commitment to critical thinking. Remind them that every time they verify before
|
||||
|
||||
sharing, they help combat misinformation.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- specific_commitment
|
||||
- thoughtful_reflection
|
||||
- basic_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
specific_commitment:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent commitment! Support their specific practice and emphasize how individual critical thinking contributes to a healthier information ecosystem.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thoughtful reflection! Encourage them to make verification a habit and to help others develop media literacy too.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
basic_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for engaging with media literacy. Emphasize the importance of these skills in the digital age.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their completion and encourage them to practice verification before sharing information.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's reflect on your learning. How will you apply media literacy skills going forward?
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,820 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
tokens_for_ai_rubric: 'Evaluate the student''s understanding of American history and historical thinking.
|
||||
|
||||
Consider:
|
||||
|
||||
- Their grasp of historical cause and effect
|
||||
|
||||
- Ability to analyze primary sources
|
||||
|
||||
- Understanding of multiple perspectives
|
||||
|
||||
- Critical thinking about historical events
|
||||
|
||||
- Connection of past events to present issues
|
||||
|
||||
|
||||
Provide encouraging feedback and suggest areas for deeper historical exploration.
|
||||
|
||||
'
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to American History
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Welcome, Historian
|
||||
content_blocks:
|
||||
- '# American History: A Critical Journey 🇺🇸'
|
||||
- Welcome to an exploration of American history that goes beyond dates and names.
|
||||
- ''
|
||||
- '**In this journey, you''ll:**'
|
||||
- '- Analyze primary sources from different historical periods'
|
||||
- '- Examine cause and effect in historical events'
|
||||
- '- Consider multiple perspectives and viewpoints'
|
||||
- '- Think critically about America''s founding principles and their evolution'
|
||||
- '- Connect historical events to contemporary issues'
|
||||
- ''
|
||||
- '**This is advanced history:**'
|
||||
- You'll be challenged to think like a historian - questioning sources, understanding context, and forming evidence-based conclusions.
|
||||
- ''
|
||||
- Ready to dive deep into American history?
|
||||
question: Are you ready to explore American history through critical thinking and primary sources?
|
||||
tokens_for_ai: 'Student expressing readiness.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- ready: Positive, ready to begin
|
||||
|
||||
- set_language: Setting language preference
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- Excellent! Let's begin with the foundations of American democracy.
|
||||
metadata_add:
|
||||
period: colonial
|
||||
next_section_and_step: founding_principles:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- I'll communicate in your preferred language.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's begin our historical journey. Are you ready to explore American history?
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
- section_id: founding_principles
|
||||
title: Founding Principles and the Constitution
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Social Contract
|
||||
content_blocks:
|
||||
- '## Philosophical Foundations 📜'
|
||||
- The American founders were heavily influenced by Enlightenment philosophy, particularly John Locke's ideas about natural rights and the social contract.
|
||||
- ''
|
||||
- '**Key Enlightenment Ideas:**'
|
||||
- '- **Natural Rights:** Locke argued that people have inherent rights to life, liberty, and property'
|
||||
- '- **Social Contract:** Government''s authority comes from the consent of the governed'
|
||||
- '- **Right to Revolution:** If government violates natural rights, people can overthrow it'
|
||||
- ''
|
||||
- '**From the Declaration of Independence (1776):**'
|
||||
- _'We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.'_
|
||||
- ''
|
||||
- '**Critical Question:**'
|
||||
- The Declaration states 'all men are created equal' - yet slavery existed, women couldn't vote, and Native Americans were displaced.
|
||||
question: How do you reconcile the contradiction between the Declaration's ideals of equality and the reality of 1776 America? What does this tell us about the founding period?
|
||||
tokens_for_ai: 'This is a sophisticated question about contradiction between ideals and reality. Look for:
|
||||
|
||||
- Recognition of the contradiction/hypocrisy
|
||||
|
||||
- Understanding of historical context (norms of the time)
|
||||
|
||||
- Nuanced thinking (ideals as aspirational vs. complete hypocrisy)
|
||||
|
||||
- Consideration of whose perspectives were included/excluded
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- sophisticated_analysis: Nuanced understanding of contradiction, historical context, and evolution of ideals
|
||||
|
||||
- recognizes_hypocrisy: Sees the contradiction clearly but may not fully analyze it
|
||||
|
||||
- contextualizes: Focuses on historical context ("people thought differently then")
|
||||
|
||||
- partial_understanding: General thoughts but incomplete analysis
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- asking_clarifying_questions: Needs more information
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Engage with their analysis thoughtfully. If they note the hypocrisy, affirm that recognition
|
||||
|
||||
and discuss how the ideals in the Declaration became tools for excluded groups (abolitionists,
|
||||
|
||||
suffragists, civil rights activists) to demand rights. If they only contextualize, acknowledge
|
||||
|
||||
historical context while noting that the contradiction was recognized even then by some.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- sophisticated_analysis
|
||||
- recognizes_hypocrisy
|
||||
- contextualizes
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- asking_clarifying_questions
|
||||
- off_topic
|
||||
transitions:
|
||||
sophisticated_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent historical thinking! Discuss how the Declaration's ideals became 'promissory notes' that future movements would claim. Mention Frederick Douglass's 1852 speech.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: founding_principles:step_2
|
||||
recognizes_hypocrisy:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good recognition of the contradiction! Expand on how these ideals, though not practiced, created a framework that excluded groups later used to demand inclusion.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: founding_principles:step_2
|
||||
contextualizes:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Historical context is important! Also note that even in the 1770s, some people (like Abigail Adams, some Quakers) pointed out these contradictions. The ideals were radical even if not fully practiced.
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: founding_principles:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking about this! Consider: the founders wrote about equality while owning slaves. How might excluded groups have used these written ideals to fight for their own rights later?'
|
||||
next_section_and_step: founding_principles:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'This is a complex question requiring deep thought. Consider: What did ''all men are created equal'' mean in practice in 1776? Who was excluded?'
|
||||
next_section_and_step: founding_principles:step_1
|
||||
asking_clarifying_questions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Answer their question about the Declaration, slavery, or founding era contradictions.
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: founding_principles:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the founding principles. How do you understand the contradiction between stated ideals and reality?
|
||||
next_section_and_step: founding_principles:step_1
|
||||
- step_id: step_2
|
||||
title: Federalism and Separation of Powers
|
||||
content_blocks:
|
||||
- '## The Constitutional Convention (1787)'
|
||||
- 'The founders faced a challenge: create a government strong enough to function, but not so strong it becomes tyrannical.'
|
||||
- ''
|
||||
- '**Their solutions:**'
|
||||
- ''
|
||||
- '**1. Federalism** - Power divided between national and state governments'
|
||||
- '**2. Separation of Powers** - Legislative, Executive, Judicial branches'
|
||||
- '**3. Checks and Balances** - Each branch can limit the others'
|
||||
- ''
|
||||
- '**Madison''s Federalist #51 (1788):**'
|
||||
- _'If men were angels, no government would be necessary. If angels were to govern men, neither external nor internal controls on government would be necessary.'_
|
||||
- ''
|
||||
- '**The founders'' key insight:**'
|
||||
- Don't rely on having virtuous leaders - design a system where ambition counteracts ambition.
|
||||
- ''
|
||||
- '**Examples of Checks and Balances:**'
|
||||
- '- President can veto laws (Executive checks Legislative)'
|
||||
- '- Congress can override veto with 2/3 vote (Legislative checks Executive)'
|
||||
- '- Supreme Court can declare laws unconstitutional (Judicial checks both)'
|
||||
- '- Senate confirms judges (Legislative checks Judicial)'
|
||||
question: Why did the founders distrust concentrated power so much? What historical experiences shaped this distrust, and do you think these checks and balances are still necessary today?
|
||||
tokens_for_ai: 'Looking for understanding of:
|
||||
|
||||
- Historical context (British monarchy, tyranny)
|
||||
|
||||
- Human nature assumptions (power corrupts)
|
||||
|
||||
- Contemporary relevance
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- excellent_analysis: Connects historical experience, theory, and contemporary relevance
|
||||
|
||||
- historical_understanding: Good grasp of why founders feared concentrated power
|
||||
|
||||
- contemporary_focus: Emphasizes modern relevance
|
||||
|
||||
- partial_understanding: General thoughts but incomplete
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Engage their thinking. The founders'' experience with King George III and colonial governors
|
||||
|
||||
shaped their views. If they discuss contemporary relevance, acknowledge different perspectives
|
||||
|
||||
on whether checks and balances are working as intended today.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- excellent_analysis
|
||||
- historical_understanding
|
||||
- contemporary_focus
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Sophisticated thinking! You've connected historical experience to institutional design and contemporary relevance. Discuss ongoing debates about executive power, judicial review, etc.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_war:step_1
|
||||
historical_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good historical understanding! The founders' experience with King George III profoundly shaped their distrust of concentrated power. Discuss how this plays out in contemporary politics.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_war:step_1
|
||||
contemporary_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'Interesting contemporary perspective! Connect this to the historical context: the founders had just fought a war against what they saw as tyrannical power.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_war:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking about this! Consider: the founders had just fought a war against King George III. How might that experience have shaped their views on power?'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: civil_war:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about what the founders had just experienced - war against British monarchy. How might that shape their views on concentrated power?
|
||||
next_section_and_step: founding_principles:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's focus on the founders' distrust of concentrated power. What historical experiences shaped this?
|
||||
next_section_and_step: founding_principles:step_2
|
||||
- section_id: civil_war
|
||||
title: The Civil War and Reconstruction
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Causes of the Civil War
|
||||
content_blocks:
|
||||
- '## The Road to Civil War ⚔️'
|
||||
- The Civil War (1861-1865) was the deadliest conflict in American history - over 600,000 deaths.
|
||||
- ''
|
||||
- '**Was it about slavery or states'' rights?**'
|
||||
- This debate continues, but let's look at primary sources.
|
||||
- ''
|
||||
- '**Mississippi''s Declaration of Secession (1861):**'
|
||||
- _'Our position is thoroughly identified with the institution of slavery - the greatest material interest of the world.'_
|
||||
- ''
|
||||
- '**Confederate VP Alexander Stephens (1861):**'
|
||||
- _'Our new government's foundations are laid, its cornerstone rests, upon the great truth that the negro is not equal to the white man; that slavery... is his natural and normal condition.'_
|
||||
- ''
|
||||
- '**Economic Context:**'
|
||||
- '- By 1860, enslaved people represented $3.5 billion in property value (more than all factories and railroads combined)'
|
||||
- '- Cotton accounted for 60% of US exports'
|
||||
- '- Southern economy was built on slave labor'
|
||||
- ''
|
||||
- '**Political Context:**'
|
||||
- '- Lincoln''s election (1860) without a single Southern electoral vote'
|
||||
- '- Fear that federal government would restrict slavery''s expansion'
|
||||
question: Based on these primary sources, what was the central cause of the Civil War? Why do you think some people today emphasize 'states' rights' rather than slavery as the cause?
|
||||
tokens_for_ai: 'Looking for:
|
||||
|
||||
- Recognition that slavery was the central cause (based on primary sources)
|
||||
|
||||
- Understanding of why revisionist narratives emerged
|
||||
|
||||
- Critical thinking about how history is remembered
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- evidence_based_conclusion: Uses primary sources to conclude slavery was central cause
|
||||
|
||||
- analyzes_revisionism: Understands why alternative narratives emerged
|
||||
|
||||
- sophisticated_both: Addresses both the historical reality and its contested memory
|
||||
|
||||
- partial_understanding: General thoughts but incomplete
|
||||
|
||||
- states_rights_focus: Emphasizes states'' rights over slavery
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'If they correctly identify slavery as the central cause, affirm this and discuss Lost Cause
|
||||
|
||||
mythology that emerged after Reconstruction. If they emphasize states'' rights, gently redirect
|
||||
|
||||
to the primary sources: Confederate states explicitly cited slavery as the reason for secession.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- evidence_based_conclusion
|
||||
- analyzes_revisionism
|
||||
- sophisticated_both
|
||||
- partial_understanding
|
||||
- states_rights_focus
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
evidence_based_conclusion:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent use of primary sources! The Confederate states' own words make clear that slavery was the central issue. Discuss how the 'Lost Cause' mythology later rewrote this history.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
primary_source_analysis: n+1
|
||||
next_section_and_step: civil_war:step_2
|
||||
analyzes_revisionism:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good analysis of historical memory! After Reconstruction, the 'Lost Cause' narrative emerged to justify the Confederacy and maintain white supremacy. Explain this further.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_war:step_2
|
||||
sophisticated_both:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Sophisticated historical thinking! You're understanding both what happened and how it's been remembered. This is advanced historical analysis.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
primary_source_analysis: n+1
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_war:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: You're thinking about this. Look at the primary sources - what did Mississippi and Confederate VP Stephens say was the reason for secession?
|
||||
next_section_and_step: civil_war:step_1
|
||||
states_rights_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'The ''states'' rights'' argument is common, but examine the primary sources: Mississippi''s declaration and Stephens'' speech explicitly state slavery was the central issue. States'' rights to do what, specifically?'
|
||||
next_section_and_step: civil_war:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Read the primary sources carefully - Mississippi's declaration and Confederate VP Stephens' speech. What do they say was the reason for secession?
|
||||
next_section_and_step: civil_war:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze the primary sources from Confederate leaders. What do they say caused the war?
|
||||
next_section_and_step: civil_war:step_1
|
||||
- step_id: step_2
|
||||
title: Reconstruction and Its Failure
|
||||
content_blocks:
|
||||
- '## Reconstruction (1865-1877)'
|
||||
- 'After the Civil War, the nation faced the question: How do you integrate 4 million formerly enslaved people into American society?'
|
||||
- ''
|
||||
- '**Constitutional Amendments:**'
|
||||
- '- **13th (1865):** Abolished slavery'
|
||||
- '- **14th (1868):** Citizenship and equal protection under law'
|
||||
- '- **15th (1870):** Voting rights regardless of race'
|
||||
- ''
|
||||
- '**Achievements of Reconstruction:**'
|
||||
- '- Black men gained voting rights and political power'
|
||||
- '- First Black Congressmen and Senators elected'
|
||||
- '- Public schools established in the South (for both Black and white children)'
|
||||
- '- Economic opportunities began to emerge'
|
||||
- ''
|
||||
- '**The Backlash:**'
|
||||
- '- White terrorist groups (KKK) used violence to suppress Black voting'
|
||||
- '- Compromise of 1877: Federal troops withdrawn from South'
|
||||
- '- Jim Crow laws established racial segregation'
|
||||
- '- Black voting rights systematically stripped through poll taxes, literacy tests, grandfather clauses'
|
||||
- ''
|
||||
- '**Historian Eric Foner:**'
|
||||
- _'Reconstruction was America's unfinished revolution.'_
|
||||
question: Why did Reconstruction fail? What would have been needed for it to succeed in achieving true equality for formerly enslaved people?
|
||||
tokens_for_ai: 'Looking for understanding of:
|
||||
|
||||
- Political will (North lost interest)
|
||||
|
||||
- White supremacist violence
|
||||
|
||||
- Economic factors (land redistribution never happened)
|
||||
|
||||
- Federal enforcement needed but withdrawn
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- multi_factor_analysis: Identifies multiple reasons for failure
|
||||
|
||||
- political_will: Focuses on loss of Northern commitment
|
||||
|
||||
- violence_focus: Emphasizes white supremacist terrorism
|
||||
|
||||
- economic_analysis: Notes lack of land redistribution/"40 acres and a mule"
|
||||
|
||||
- thoughtful_counterfactual: Proposes what could have made it succeed
|
||||
|
||||
- partial_understanding: General thoughts
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Engage their analysis. Multiple factors contributed: Northern fatigue, white supremacist
|
||||
|
||||
violence, economic exploitation, political compromise. If they propose counterfactuals,
|
||||
|
||||
discuss land redistribution, sustained federal protection, economic investment.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- multi_factor_analysis
|
||||
- political_will
|
||||
- violence_focus
|
||||
- economic_analysis
|
||||
- thoughtful_counterfactual
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
multi_factor_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent multi-factor analysis! Reconstruction failed due to loss of political will, white supremacist violence, economic exploitation, and the Compromise of 1877. Discuss long-term consequences.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_rights:step_1
|
||||
political_will:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Important factor! The North did lose interest after the Compromise of 1877. Also consider white supremacist violence and economic factors.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_rights:step_1
|
||||
violence_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Crucial point! White terrorism (KKK, etc.) was systematically used to suppress Black political power. The federal government eventually stopped protecting Black citizens.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_rights:step_1
|
||||
economic_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Key economic insight! Without land redistribution ('40 acres and a mule'), formerly enslaved people remained economically dependent on white landowners through sharecropping.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_rights:step_1
|
||||
thoughtful_counterfactual:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Interesting counterfactual thinking! Evaluate their proposals against historical context and constraints.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_rights:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking about this. Consider: political will, violence, economics, and federal enforcement. What combination of factors led to failure?'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: civil_rights:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Think about what Reconstruction needed: political commitment, protection from violence, economic opportunity, federal enforcement. What went wrong?'
|
||||
next_section_and_step: civil_war:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze Reconstruction's failure. What factors led to the end of Black political power after 1877?
|
||||
next_section_and_step: civil_war:step_2
|
||||
- section_id: civil_rights
|
||||
title: Civil Rights Movement
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Strategies for Change
|
||||
content_blocks:
|
||||
- '## The Civil Rights Movement (1950s-1960s) ✊'
|
||||
- Nearly 100 years after the Civil War, Jim Crow segregation still dominated the South.
|
||||
- ''
|
||||
- '**Different Strategic Approaches:**'
|
||||
- ''
|
||||
- '**Legal Strategy (NAACP, Thurgood Marshall):**'
|
||||
- '- Use courts to overturn segregation laws'
|
||||
- '- *Brown v. Board of Education* (1954): Declared school segregation unconstitutional'
|
||||
- '- Gradualist approach working within the system'
|
||||
- ''
|
||||
- '**Nonviolent Direct Action (MLK, SCLC):**'
|
||||
- '- Boycotts, sit-ins, marches to create crisis that forces negotiation'
|
||||
- '- Montgomery Bus Boycott (1955-56), March on Washington (1963)'
|
||||
- '- Moral appeal to conscience of nation'
|
||||
- ''
|
||||
- '**Black Power/Self-Defense (Malcolm X, Black Panthers):**'
|
||||
- '- Critique of integration as goal; emphasis on Black empowerment'
|
||||
- '- Self-defense against violence (vs. absolute nonviolence)'
|
||||
- '- Economic self-sufficiency and cultural pride'
|
||||
- ''
|
||||
- '**MLK''s Letter from Birmingham Jail (1963):**'
|
||||
- _'Injustice anywhere is a threat to justice everywhere. We are caught in an inescapable network of mutuality, tied in a single garment of destiny.'_
|
||||
- ''
|
||||
- '**Malcolm X (1964):**'
|
||||
- _'We declare our right on this earth to be a man, to be a human being, to be respected as a human being, to be given the rights of a human being in this society.'_
|
||||
question: Why were there different strategic approaches in the Civil Rights Movement? Were all of these approaches necessary, or was one more effective than others? Explain your reasoning.
|
||||
tokens_for_ai: 'Looking for:
|
||||
|
||||
- Understanding of different strategic visions
|
||||
|
||||
- Recognition that strategies complemented each other
|
||||
|
||||
- Sophisticated thinking about social movements
|
||||
|
||||
- Awareness that movements aren''t monolithic
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- sophisticated_analysis: Understands how different strategies played different roles
|
||||
|
||||
- complementary_view: Sees strategies as working together
|
||||
|
||||
- single_strategy_preference: Argues one was most effective
|
||||
|
||||
- comparative_analysis: Thoughtfully compares approaches
|
||||
|
||||
- partial_understanding: General thoughts
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Engage their analysis thoughtfully. Historical consensus is that multiple strategies created
|
||||
|
||||
pressure from different angles: legal victories removed legal barriers, direct action created
|
||||
|
||||
urgency, Black Power empowered communities and pushed moderates to negotiate. If they prefer
|
||||
|
||||
one strategy, discuss how it interacted with others.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- sophisticated_analysis
|
||||
- complementary_view
|
||||
- single_strategy_preference
|
||||
- comparative_analysis
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
sophisticated_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent historical thinking! You understand that social movements use multiple strategies simultaneously. The 'radical flank effect' made moderates seem more reasonable to white Americans.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_rights:step_2
|
||||
complementary_view:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good insight! The different strategies created pressure from multiple angles and appealed to different constituencies. Discuss the 'radical flank effect.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_rights:step_2
|
||||
single_strategy_preference:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You make a case for one strategy. Also consider how the strategies interacted: legal victories needed enforcement, which required political pressure from protests.'
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: civil_rights:step_2
|
||||
comparative_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good comparative thinking! Expand on how the strategies might have complemented each other or created tension.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: civil_rights:step_2
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Think about how different strategies might work together. Could 'radical' demands make 'moderate' demands seem more acceptable?
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: civil_rights:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- 'Consider: Why might a movement need both people working within the system (courts) and outside it (protests)? How might they complement each other?'
|
||||
next_section_and_step: civil_rights:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's analyze the different Civil Rights strategies. How did legal, nonviolent direct action, and Black Power approaches differ?
|
||||
next_section_and_step: civil_rights:step_1
|
||||
- step_id: step_2
|
||||
title: Unfinished Business
|
||||
content_blocks:
|
||||
- '## The Civil Rights Movement''s Legacy'
|
||||
- 'The Civil Rights Movement achieved major legal victories:'
|
||||
- '- Civil Rights Act (1964): Outlawed discrimination'
|
||||
- '- Voting Rights Act (1965): Prohibited racial discrimination in voting'
|
||||
- '- Fair Housing Act (1968): Prohibited discrimination in housing'
|
||||
- ''
|
||||
- '**But many goals remained unachieved:**'
|
||||
- ''
|
||||
- '**Economic Justice:**'
|
||||
- MLK's focus in final years was on poverty - the Poor People's Campaign
|
||||
- 'Wealth gap: In 1963, median Black family had 5% of white family wealth. In 2016: 10%'
|
||||
- ''
|
||||
- '**Systemic Issues:**'
|
||||
- '- School resegregation (integration peaked in 1988, has declined since)'
|
||||
- '- Mass incarceration (5x incarceration rate for Black vs white Americans)'
|
||||
- '- Voting rights: Shelby County v. Holder (2013) weakened Voting Rights Act'
|
||||
- ''
|
||||
- '**MLK''s Final Speech (1968, night before assassination):**'
|
||||
- _'I've been to the mountaintop... I've seen the Promised Land. I may not get there with you. But I want you to know tonight, that we, as a people, will get to the Promised Land.'_
|
||||
question: The Civil Rights Movement won major legal battles but many economic and systemic issues persist. Why do legal victories not automatically solve social problems? What more is needed beyond changing laws?
|
||||
tokens_for_ai: 'Looking for understanding that:
|
||||
|
||||
- Laws vs. implementation/enforcement
|
||||
|
||||
- Formal equality vs. substantive equality
|
||||
|
||||
- Systemic/structural issues
|
||||
|
||||
- Cultural change, economic redistribution, enforcement
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- systemic_understanding: Grasps difference between formal and substantive equality
|
||||
|
||||
- implementation_focus: Emphasizes gap between law and enforcement
|
||||
|
||||
- cultural_change: Notes need for changing hearts and minds
|
||||
|
||||
- economic_analysis: Focuses on material/economic dimensions
|
||||
|
||||
- sophisticated_multi_factor: Identifies multiple dimensions of change needed
|
||||
|
||||
- partial_understanding: General thoughts
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Engage their thinking about social change. Legal change is necessary but not sufficient.
|
||||
|
||||
Systemic change requires enforcement, cultural shift, economic redistribution, and
|
||||
|
||||
addressing structural inequalities. If they give sophisticated analysis, affirm it.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- systemic_understanding
|
||||
- implementation_focus
|
||||
- cultural_change
|
||||
- economic_analysis
|
||||
- sophisticated_multi_factor
|
||||
- partial_understanding
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
systemic_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent grasp of the difference between formal and substantive equality! Laws change what's legal, but systemic change requires transforming institutions, culture, and economic structures.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
implementation_focus:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Important point! There's often a gap between laws on the books and their enforcement. Discuss how enforcement requires political will and resources.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: conclusion:step_1
|
||||
cultural_change:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Good insight about cultural change! Laws can change behavior, but cultural attitudes also need to shift. This is a slow, complex process.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: conclusion:step_1
|
||||
economic_analysis:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Strong economic analysis! Legal equality doesn't address wealth gaps, employment discrimination, or economic structures. MLK increasingly focused on economic justice in his final years.
|
||||
metadata_add:
|
||||
score: n+2
|
||||
next_section_and_step: conclusion:step_1
|
||||
sophisticated_multi_factor:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Outstanding multi-dimensional analysis! You understand that social change requires legal, cultural, economic, and institutional transformation. This is advanced historical thinking.
|
||||
metadata_add:
|
||||
score: n+3
|
||||
critical_thinking: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: 'You''re thinking about this. Consider: if a law is passed but not enforced, or if economic structures remain unchanged, what''s the impact?'
|
||||
metadata_add:
|
||||
score: n+1
|
||||
next_section_and_step: conclusion:step_1
|
||||
limited_effort:
|
||||
content_blocks:
|
||||
- Think about the difference between laws changing and society changing. What else needs to happen beyond passing legislation?
|
||||
next_section_and_step: civil_rights:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Let's think about why legal victories aren't enough. What more is needed for real social change?
|
||||
next_section_and_step: civil_rights:step_2
|
||||
- section_id: conclusion
|
||||
title: Historical Thinking and Contemporary Connections
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Thinking Like a Historian
|
||||
content_blocks:
|
||||
- '## Congratulations, Historian! 🎓'
|
||||
- You've engaged with American history at an advanced level.
|
||||
- ''
|
||||
- '**Key Historical Thinking Skills You''ve Practiced:**'
|
||||
- ✓ **Primary Source Analysis** - Reading founding documents and speeches in context
|
||||
- ✓ **Cause and Effect** - Understanding how events lead to consequences
|
||||
- ✓ **Multiple Perspectives** - Considering different viewpoints on events
|
||||
- ✓ **Continuity and Change** - Seeing patterns and transformations over time
|
||||
- ✓ **Historical Significance** - Evaluating which events and ideas matter and why
|
||||
- ✓ **Connecting Past to Present** - Understanding how history shapes current issues
|
||||
- ''
|
||||
- '**Themes Across American History:**'
|
||||
- '- Tension between ideals and reality (equality vs. practice)'
|
||||
- '- Struggles to expand democracy and rights'
|
||||
- '- Economic factors shaping politics and society'
|
||||
- '- Power of social movements to create change'
|
||||
- '- Importance of institutions and their design'
|
||||
- ''
|
||||
- '**Why History Matters:**'
|
||||
- '- Understand how we got here'
|
||||
- '- Learn from past successes and failures'
|
||||
- '- Recognize patterns and precedents'
|
||||
- '- Think critically about present claims using historical evidence'
|
||||
- '- Understand that change is possible because it has happened before'
|
||||
- ''
|
||||
- '**''Those who cannot remember the past are condemned to repeat it.''** - George Santayana'
|
||||
question: What's one historical insight from this activity that changes how you think about a contemporary issue? How does understanding history help you think more critically about the present?
|
||||
tokens_for_ai: 'This is a reflection on applying historical thinking to contemporary issues.
|
||||
|
||||
|
||||
Categorize as:
|
||||
|
||||
- specific_connection: Makes clear connection between historical insight and contemporary issue
|
||||
|
||||
- thoughtful_reflection: Meaningful reflection on historical thinking
|
||||
|
||||
- general_reflection: Broader thoughts about history''s relevance
|
||||
|
||||
- limited_effort: Very brief
|
||||
|
||||
- off_topic: Unrelated
|
||||
|
||||
'
|
||||
feedback_tokens_for_ai: 'Provide thoughtful, personalized feedback on their historical journey. Acknowledge specific
|
||||
|
||||
insights they shared throughout the activity. Encourage continued historical thinking and
|
||||
|
||||
exploration. Discuss how understanding history makes us better citizens.
|
||||
|
||||
'
|
||||
buckets:
|
||||
- specific_connection
|
||||
- thoughtful_reflection
|
||||
- general_reflection
|
||||
- limited_effort
|
||||
- off_topic
|
||||
transitions:
|
||||
specific_connection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Excellent application of historical thinking to contemporary issues! Affirm their specific connection and discuss how historians analyze present events using historical frameworks.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thoughtful reflection on historical thinking! Encourage them to continue asking historical questions about contemporary issues.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
general_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Thank them for engaging deeply with American history. Suggest specific historical topics or periods they might explore further based on their interests.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
limited_effort:
|
||||
ai_feedback:
|
||||
tokens_for_ai: Acknowledge their completion and encourage them to think about how historical patterns might illuminate current events.
|
||||
metadata_add:
|
||||
activity_completed: 'true'
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- Reflect on your historical journey. What insight about the past helps you understand the present differently?
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,591 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate the student's engagement with fashion concepts.
|
||||
|
||||
Consider:
|
||||
- Their understanding of personal style
|
||||
- Creativity in fashion choices
|
||||
- Awareness of fashion principles (color, fit, occasion)
|
||||
- Confidence in expressing their style
|
||||
|
||||
Provide encouraging, personalized fashion advice.
|
||||
Be supportive of all style preferences and body types.
|
||||
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Fashion Today
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Fashion Journey Begins
|
||||
content_blocks:
|
||||
- "# Welcome to Fashion Today! 👗✨"
|
||||
- "Fashion is more than clothes—it's self-expression, confidence, and creativity!"
|
||||
- ""
|
||||
- "**In this journey, you'll:**"
|
||||
- "- Discover your personal style"
|
||||
- "- Learn fashion principles"
|
||||
- "- Build outfits for different occasions"
|
||||
- "- Get personalized style advice"
|
||||
- ""
|
||||
- "**Remember:** Fashion has no rules, only guidelines. The best style is what makes YOU feel confident!"
|
||||
question: Are you ready to explore the exciting world of fashion?
|
||||
tokens_for_ai: |
|
||||
Accept any positive response as 'ready'.
|
||||
If setting language preference, categorize as 'set_language'.
|
||||
Otherwise 'off_topic'.
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- "Fantastic! Let's discover your unique style! 🌟"
|
||||
next_section_and_step: style_discovery:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on fashion! Are you excited to begin?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: style_discovery
|
||||
title: Discover Your Style
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Fashion Inspiration
|
||||
content_blocks:
|
||||
- "## What's Your Style Vibe? 🎨"
|
||||
- ""
|
||||
- "**Popular fashion styles:**"
|
||||
- ""
|
||||
- "**Classic/Timeless** 🎩 - Elegant, tailored pieces; neutral colors; quality over trends"
|
||||
- "**Casual/Comfortable** 👟 - Relaxed fits, denim, sneakers, effortless cool"
|
||||
- "**Bohemian/Boho** 🌸 - Flowy fabrics, earthy tones, layered accessories, free-spirited"
|
||||
- "**Streetwear/Urban** 🛹 - Bold graphics, sneakers, hoodies, influenced by music and skate culture"
|
||||
- "**Romantic/Feminine** 🌹 - Soft colors, ruffles, lace, delicate details"
|
||||
- "**Edgy/Alternative** 🖤 - Dark colors, leather, unconventional cuts, statement pieces"
|
||||
- "**Minimalist** ⚪ - Clean lines, monochrome, simple silhouettes, 'less is more'"
|
||||
- "**Preppy/Collegiate** 📚 - Polished, structured, blazers, button-downs, classic patterns"
|
||||
- "**Glamorous/Luxe** ✨ - Sparkle, bold jewelry, luxurious fabrics, red carpet vibes"
|
||||
- "**Eclectic/Mix-and-Match** 🎭 - Combining different styles, unique combinations, personal flair"
|
||||
- ""
|
||||
- "You can love multiple styles or create your own unique blend!"
|
||||
question: Which style (or styles) resonates with you? Describe what you love about fashion or what you'd like to wear!
|
||||
tokens_for_ai: |
|
||||
The student is describing their fashion preferences.
|
||||
|
||||
Store their response in metadata.style_preference.
|
||||
|
||||
Categorize based on engagement level:
|
||||
- detailed_response: They describe specific styles, colors, or preferences
|
||||
- general_interest: They mention a style category or general interest
|
||||
- exploring: They're unsure but curious
|
||||
- set_language: Setting language preference
|
||||
- off_topic: Unrelated to fashion
|
||||
feedback_tokens_for_ai: |
|
||||
Acknowledge their style preferences enthusiastically!
|
||||
|
||||
If they mentioned specific styles:
|
||||
- Validate their choices
|
||||
- Mention how that style expresses personality
|
||||
- Suggest complementary elements
|
||||
|
||||
If they're exploring:
|
||||
- Encourage experimentation
|
||||
- Mention that style evolves
|
||||
- Suggest trying different looks
|
||||
buckets:
|
||||
- detailed_response
|
||||
- general_interest
|
||||
- exploring
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
detailed_response:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Celebrate their detailed style knowledge!
|
||||
Reference specific elements they mentioned.
|
||||
Tell them their style sounds amazing and expresses their personality.
|
||||
metadata_add:
|
||||
style_preference: "the-users-response"
|
||||
score: "n+1"
|
||||
next_section_and_step: style_discovery:step_2
|
||||
general_interest:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great starting point!
|
||||
Acknowledge their style interest.
|
||||
Encourage them to explore further.
|
||||
metadata_add:
|
||||
style_preference: "the-users-response"
|
||||
next_section_and_step: style_discovery:step_2
|
||||
exploring:
|
||||
content_blocks:
|
||||
- "Exploring is wonderful! Fashion is about discovery."
|
||||
- "Think about: What colors make you happy? What fabrics feel good? What makes you feel confident?"
|
||||
metadata_add:
|
||||
style_preference: "exploring different styles"
|
||||
next_section_and_step: style_discovery:step_2
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: style_discovery:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's talk fashion! What kind of clothes do you enjoy wearing?"
|
||||
next_section_and_step: style_discovery:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Color and You
|
||||
content_blocks:
|
||||
- "## The Power of Color 🌈"
|
||||
- ""
|
||||
- "Colors affect mood and perception!"
|
||||
- ""
|
||||
- "**Color Psychology:**"
|
||||
- "- **Red** ❤️ - Bold, confident, passionate, attention-grabbing"
|
||||
- "- **Blue** 💙 - Calm, trustworthy, professional, serene"
|
||||
- "- **Black** 🖤 - Sophisticated, elegant, powerful, versatile"
|
||||
- "- **White** 🤍 - Clean, fresh, minimalist, peaceful"
|
||||
- "- **Yellow** 💛 - Happy, energetic, optimistic, cheerful"
|
||||
- "- **Green** 💚 - Natural, balanced, refreshing, growth"
|
||||
- "- **Pink** 💗 - Playful, romantic, soft, youthful"
|
||||
- "- **Purple** 💜 - Creative, luxurious, mysterious, royal"
|
||||
- "- **Neutrals** (beige, gray, brown) - Versatile, timeless, easy to mix"
|
||||
- ""
|
||||
- "**Pro Tip:** Wear colors near your face that complement your skin tone!"
|
||||
question: What colors do you love to wear? What colors make you feel most confident or happy?
|
||||
tokens_for_ai: |
|
||||
Student is sharing color preferences.
|
||||
|
||||
Categorize as:
|
||||
- specific_colors: Names specific colors and why they like them
|
||||
- color_mentioned: Mentions colors without detail
|
||||
- neutral_preference: Prefers neutrals or all colors
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Validate their color choices!
|
||||
|
||||
Reference color psychology for their chosen colors.
|
||||
Suggest how to incorporate those colors.
|
||||
Mention complementary colors if appropriate.
|
||||
buckets:
|
||||
- specific_colors
|
||||
- color_mentioned
|
||||
- neutral_preference
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
specific_colors:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent color awareness!
|
||||
Reference the psychology/meaning of their chosen colors.
|
||||
Suggest outfit combinations or accent pieces.
|
||||
Celebrate their color confidence!
|
||||
metadata_add:
|
||||
color_preference: "the-users-response"
|
||||
score: "n+1"
|
||||
next_section_and_step: outfit_building:step_1
|
||||
color_mentioned:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great choices!
|
||||
Explain what those colors convey.
|
||||
Encourage experimenting with different shades.
|
||||
metadata_add:
|
||||
color_preference: "the-users-response"
|
||||
next_section_and_step: outfit_building:step_1
|
||||
neutral_preference:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Neutrals are timeless and versatile!
|
||||
Perfect base for any wardrobe.
|
||||
Suggest adding pops of color through accessories.
|
||||
metadata_add:
|
||||
color_preference: "neutrals and versatile colors"
|
||||
next_section_and_step: outfit_building:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: style_discovery:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think about your wardrobe! What colors do you reach for most often?"
|
||||
next_section_and_step: style_discovery:step_2
|
||||
|
||||
- section_id: outfit_building
|
||||
title: Build Your Wardrobe
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Dressing for Occasions
|
||||
content_blocks:
|
||||
- "## Fashion for Every Occasion 👔👗"
|
||||
- ""
|
||||
- "**The Fashion Formula:** Occasion + Personal Style = Perfect Outfit"
|
||||
- ""
|
||||
- "**Key Principles:**"
|
||||
- ""
|
||||
- "1. **Dress Code Awareness**"
|
||||
- " - Casual: Comfort meets style (jeans, sneakers, t-shirts)"
|
||||
- " - Business Casual: Polished but approachable (slacks, blouses, loafers)"
|
||||
- " - Formal: Sophisticated elegance (suits, dresses, dress shoes)"
|
||||
- ""
|
||||
- "2. **Fit is Everything**"
|
||||
- " - Clothes should fit your body, not the other way around"
|
||||
- " - Tailoring can transform any piece"
|
||||
- " - Comfort = Confidence"
|
||||
- ""
|
||||
- "3. **The Power of Accessories**"
|
||||
- " - Jewelry, bags, shoes, scarves"
|
||||
- " - Can transform a basic outfit"
|
||||
- " - Express personality"
|
||||
- ""
|
||||
- "**Let's practice outfit building!**"
|
||||
question: "Imagine you're going to a casual coffee date with friends. What would you wear? Describe your outfit!"
|
||||
tokens_for_ai: |
|
||||
Student is describing a casual outfit.
|
||||
|
||||
Look for:
|
||||
- Specific clothing items
|
||||
- Color coordination
|
||||
- Style consistency
|
||||
- Occasion appropriateness
|
||||
|
||||
Categorize as:
|
||||
- detailed_outfit: Describes multiple pieces with thought to coordination
|
||||
- basic_outfit: Mentions clothing items appropriately casual
|
||||
- creative_outfit: Unique or interesting combinations
|
||||
- needs_guidance: Very brief or doesn't match occasion
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Evaluate their outfit for the casual coffee date scenario.
|
||||
|
||||
If well thought out:
|
||||
- Praise specific choices
|
||||
- Mention what works well
|
||||
- Suggest one accessory or detail to elevate it
|
||||
|
||||
If creative:
|
||||
- Celebrate their unique style
|
||||
- Encourage personal expression
|
||||
|
||||
If needs work:
|
||||
- Gently guide toward casual appropriate pieces
|
||||
- Give specific suggestions
|
||||
- Be encouraging
|
||||
buckets:
|
||||
- detailed_outfit
|
||||
- basic_outfit
|
||||
- creative_outfit
|
||||
- needs_guidance
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
detailed_outfit:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent outfit planning!
|
||||
Reference their style preference from metadata if stored.
|
||||
Praise specific elements (color choices, coordination, etc.).
|
||||
Suggest one perfect accessory to complete the look.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
outfits_created: "n+1"
|
||||
next_section_and_step: outfit_building:step_2
|
||||
basic_outfit:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect for a casual coffee date!
|
||||
Reference what they chose.
|
||||
Suggest how to add personal flair (accessories, colors, etc.).
|
||||
metadata_add:
|
||||
outfits_created: "n+1"
|
||||
next_section_and_step: outfit_building:step_2
|
||||
creative_outfit:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Love the creativity!
|
||||
Celebrate their unique fashion sense.
|
||||
Encourage them to own their style.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
outfits_created: "n+1"
|
||||
next_section_and_step: outfit_building:step_2
|
||||
needs_guidance:
|
||||
content_blocks:
|
||||
- "Let's think casual and comfortable!"
|
||||
- "**Suggestions:** Jeans or casual pants, a nice top or sweater, comfortable shoes (sneakers, boots, flats)"
|
||||
- "Add your personal touch with accessories or colors you love!"
|
||||
next_section_and_step: outfit_building:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: outfit_building:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Imagine your perfect casual outfit! What would you choose to wear for coffee with friends?"
|
||||
next_section_and_step: outfit_building:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Statement Pieces
|
||||
content_blocks:
|
||||
- "## The Power of Statement Pieces 💎"
|
||||
- ""
|
||||
- "**What's a Statement Piece?**"
|
||||
- "An item that stands out and defines your outfit!"
|
||||
- ""
|
||||
- "**Examples:**"
|
||||
- "- Bold jacket (leather, colorful blazer, denim)"
|
||||
- "- Eye-catching shoes (colored sneakers, boots, heels)"
|
||||
- "- Unique bag (vintage, designer, handmade)"
|
||||
- "- Dramatic jewelry (chunky necklace, statement earrings)"
|
||||
- "- Printed/patterned piece (floral dress, graphic tee, plaid pants)"
|
||||
- ""
|
||||
- "**The Rule:** Let your statement piece shine!"
|
||||
- "- Keep other items simpler"
|
||||
- "- Build outfit around the statement piece"
|
||||
- "- One or two statement pieces max"
|
||||
question: What's your favorite statement piece you own (or would love to own)? Describe it and how you'd style it!
|
||||
tokens_for_ai: |
|
||||
Student describing a statement piece.
|
||||
|
||||
Categorize as:
|
||||
- detailed_vision: Describes the piece AND how they'd wear it
|
||||
- piece_described: Describes a statement item
|
||||
- aspirational: Talks about wanting certain pieces
|
||||
- minimalist_approach: Prefers subtle/no statement pieces
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Respond to their statement piece choice!
|
||||
|
||||
If they described styling:
|
||||
- Praise their fashion vision
|
||||
- Suggest complementary pieces
|
||||
- Encourage them to rock it
|
||||
|
||||
If minimalist:
|
||||
- Validate that style too
|
||||
- Mention statement can be subtle
|
||||
- Quality basics are statements too
|
||||
buckets:
|
||||
- detailed_vision
|
||||
- piece_described
|
||||
- aspirational
|
||||
- minimalist_approach
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
detailed_vision:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Wow, you have a great fashion eye!
|
||||
Love how you described both the piece and the styling.
|
||||
Reference specific elements they mentioned.
|
||||
Encourage them to wear it with confidence!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
piece_described:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great statement piece choice!
|
||||
Suggest how to style it.
|
||||
Mention what type of outfit it would elevate.
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
aspirational:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great fashion goals!
|
||||
Encourage saving/hunting for that perfect piece.
|
||||
Mention alternatives or similar items to explore.
|
||||
Fashion dreams are fun!
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
minimalist_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Minimalism is a powerful statement!
|
||||
Quality over quantity is wise.
|
||||
Mention how simple pieces can be impactful.
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: outfit_building:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think about your wardrobe! Do you have a favorite bold piece that makes an outfit special?"
|
||||
next_section_and_step: outfit_building:step_2
|
||||
|
||||
- section_id: fashion_wisdom
|
||||
title: Fashion Tips & Confidence
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Your Fashion Philosophy
|
||||
content_blocks:
|
||||
- "## Fashion Wisdom 🌟"
|
||||
- ""
|
||||
- "**Universal Fashion Truths:**"
|
||||
- ""
|
||||
- "1. **Confidence is Your Best Accessory**"
|
||||
- " - Wear what makes YOU feel amazing"
|
||||
- " - Own your choices"
|
||||
- ""
|
||||
- "2. **Fashion Has No Size**"
|
||||
- " - Every body is a fashion body"
|
||||
- " - Dress for YOUR shape and comfort"
|
||||
- ""
|
||||
- "3. **Break the Rules**"
|
||||
- " - Fashion 'rules' are just suggestions"
|
||||
- " - Mix patterns, clash colors, be YOU"
|
||||
- ""
|
||||
- "4. **Sustainable Choices Matter**"
|
||||
- " - Quality over quantity"
|
||||
- " - Thrift, swap, upcycle"
|
||||
- " - Fashion can be ethical"
|
||||
- ""
|
||||
- "5. **Express Yourself**"
|
||||
- " - Your clothes tell your story"
|
||||
- " - Change your style as you grow"
|
||||
- " - Have fun with it!"
|
||||
question: What does fashion mean to you? How do you want to express yourself through clothing?
|
||||
tokens_for_ai: |
|
||||
This is a reflection question about their fashion philosophy.
|
||||
|
||||
Categorize as:
|
||||
- thoughtful_reflection: Shares personal connection to fashion
|
||||
- self_expression: Talks about expressing personality/identity
|
||||
- practical_view: Focuses on function, comfort, practicality
|
||||
- creative_view: Sees fashion as art/creativity
|
||||
- brief_response: Short but genuine
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Provide personalized, encouraging feedback!
|
||||
|
||||
Reference their style_preference from metadata if available.
|
||||
Celebrate their unique perspective on fashion.
|
||||
Encourage them to continue expressing themselves.
|
||||
Mention that fashion is a journey, not a destination.
|
||||
buckets:
|
||||
- thoughtful_reflection
|
||||
- self_expression
|
||||
- practical_view
|
||||
- creative_view
|
||||
- brief_response
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
thoughtful_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Beautiful reflection on fashion!
|
||||
Acknowledge their personal connection.
|
||||
Reference their journey through this activity.
|
||||
Encourage continued self-expression.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
activity_completed: "true"
|
||||
next_section_and_step: conclusion:step_1
|
||||
self_expression:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Fashion is the perfect medium for self-expression!
|
||||
Celebrate their desire to show their personality.
|
||||
Encourage authenticity in their style choices.
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: conclusion:step_1
|
||||
practical_view:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Practical fashion is smart fashion!
|
||||
Function and style can coexist beautifully.
|
||||
Acknowledge the value of comfort and versatility.
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: conclusion:step_1
|
||||
creative_view:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Fashion IS art!
|
||||
Celebrate their creative perspective.
|
||||
Encourage experimenting and pushing boundaries.
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: conclusion:step_1
|
||||
brief_response:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Thank them for sharing!
|
||||
Summarize key fashion principles from this activity.
|
||||
Encourage them to keep exploring their style.
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: conclusion:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's reflect on fashion! What role do clothes play in your life and how you present yourself?"
|
||||
next_section_and_step: fashion_wisdom:step_1
|
||||
|
||||
- section_id: conclusion
|
||||
title: Your Fashion Journey Continues
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Keep Shining
|
||||
content_blocks:
|
||||
- "## You're a Fashion Star! ⭐✨"
|
||||
- ""
|
||||
- "**What You've Explored:**"
|
||||
- "✓ Discovered your personal style"
|
||||
- "✓ Learned about colors and their power"
|
||||
- "✓ Built outfits for different occasions"
|
||||
- "✓ Explored statement pieces"
|
||||
- "✓ Defined your fashion philosophy"
|
||||
- ""
|
||||
- "**Remember:**"
|
||||
- "- Fashion is about feeling good in your skin"
|
||||
- "- Confidence is the key to any outfit"
|
||||
- "- Your style will evolve—embrace it!"
|
||||
- "- There are no mistakes in fashion, only experiments"
|
||||
- ""
|
||||
- "**Next Steps:**"
|
||||
- "- Clean out your closet (donate what doesn't serve you)"
|
||||
- "- Try one new style element this week"
|
||||
- "- Mix pieces you've never combined before"
|
||||
- "- Take photos of outfits you love"
|
||||
- "- Follow fashion inspiration that resonates with YOU"
|
||||
- ""
|
||||
- "**Your style is uniquely YOURS. Wear it proudly! 💖**"
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Mario"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Who is Mario?"
|
||||
content_blocks:
|
||||
- "Welcome to the Mario trivia game!"
|
||||
#- "Mario is a famous video game character created by Nintendo. He is known for his adventures in various games."
|
||||
tokens_for_ai: "Explain who Mario is and his significance in video games in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Who is Mario?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know who Mario is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Mario. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Mario."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Mario in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Mario's First Game"
|
||||
content_blocks: []
|
||||
#content_blocks:
|
||||
# - "Mario first appeared in the game Donkey Kong in 1981."
|
||||
# - "In this game, Mario had to rescue a damsel in distress from a giant ape named Donkey Kong."
|
||||
tokens_for_ai: "Explain Mario's first appearance in video games in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What was the first game Mario appeared in?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about Mario's first game."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Mario's first game. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Mario's first game."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Mario's first game in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Mario's Friends and Foes"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Mario's Friends"
|
||||
content_blocks:
|
||||
- "Mario has many friends who help him on his adventures."
|
||||
#- "Some of his friends include Luigi, Princess Peach, and Yoshi."
|
||||
tokens_for_ai: "Explain who Mario's friends are in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some of Mario's friends?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about Mario's friends."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Mario's friends. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Mario's friends."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Mario's friends in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Mario's Foes"
|
||||
content_blocks:
|
||||
- "Mario also has many enemies that he has to defeat."
|
||||
#- "Some of his foes include Bowser, Goombas, and Koopa Troopas."
|
||||
tokens_for_ai: "Explain who Mario's foes are in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some of Mario's foes?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about Mario's foes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Mario's foes. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Mario's foes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Mario's foes in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Mario's Adventures"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Super Mario Bros."
|
||||
content_blocks:
|
||||
- "One of the most famous Mario games is Super Mario Bros., released in 1985."
|
||||
#- "In this game, Mario must rescue Princess Peach from Bowser."
|
||||
tokens_for_ai: "Explain the game Super Mario Bros. in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the main objective in Super Mario Bros.?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know the main objective in Super Mario Bros."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Super Mario Bros. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Super Mario Bros."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Super Mario Bros. in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Mario Kart"
|
||||
content_blocks:
|
||||
- "Mario Kart is a popular racing game series featuring Mario and his friends."
|
||||
#- "Players race against each other on various tracks and use items to gain an advantage."
|
||||
tokens_for_ai: "Explain the game Mario Kart in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the main objective in Mario Kart?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know the main objective in Mario Kart."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Mario Kart. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Mario Kart."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Mario Kart in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Mario's Power-Ups"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Super Mushroom"
|
||||
content_blocks: []
|
||||
#content_blocks:
|
||||
# - "The Super Mushroom is a power-up that makes Mario grow bigger."
|
||||
# - "It allows Mario to take an extra hit from enemies."
|
||||
tokens_for_ai: "Explain the Super Mushroom power-up in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What does the Super Mushroom do?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know what the Super Mushroom does."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about the Super Mushroom. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Super Mushroom."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Super Mushroom in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Fire Flower"
|
||||
content_blocks: []
|
||||
#content_blocks:
|
||||
# - "The Fire Flower is a power-up that gives Mario the ability to throw fireballs."
|
||||
# - "It allows Mario to defeat enemies from a distance."
|
||||
tokens_for_ai: "Explain the Fire Flower power-up in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What does the Fire Flower do?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know what the Fire Flower does."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about the Fire Flower. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Fire Flower."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Fire Flower in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Mario's Worlds"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Mushroom Kingdom"
|
||||
content_blocks: []
|
||||
#content_blocks:
|
||||
# - "The Mushroom Kingdom is the main setting for many Mario games."
|
||||
# - "It is ruled by Princess Peach and is often threatened by Bowser."
|
||||
tokens_for_ai: "Explain the Mushroom Kingdom in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the Mushroom Kingdom?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about the Mushroom Kingdom."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about the Mushroom Kingdom. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the Mushroom Kingdom."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the Mushroom Kingdom in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Bowser's Castle"
|
||||
content_blocks: []
|
||||
#content_blocks:
|
||||
# - "Bowser's Castle is the home of Mario's arch-enemy, Bowser."
|
||||
# - "It is often the final level in many Mario games, where Mario must defeat Bowser to rescue Princess Peach."
|
||||
tokens_for_ai: "Explain Bowser's Castle in a friendly and engaging manner suitable for a 13-year-old. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is Bowser's Castle?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about Bowser's Castle."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Bowser's Castle. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Bowser's Castle."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Bowser's Castle in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The End."
|
||||
content_blocks:
|
||||
- "The End."
|
||||
|
||||
|
|
@ -1,786 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate the student's understanding of basic statistical concepts.
|
||||
|
||||
Consider:
|
||||
- Grasp of central tendency (mean, median, mode)
|
||||
- Understanding of variation and spread
|
||||
- Ability to interpret data
|
||||
- Recognition of distributions
|
||||
- Practical application of concepts
|
||||
|
||||
Provide clear explanations with real-world examples.
|
||||
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Statistics
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Why Statistics Matters
|
||||
content_blocks:
|
||||
- "# Statistics 101: Making Sense of Data 📊"
|
||||
- ""
|
||||
- "**Welcome to the world of statistics!**"
|
||||
- ""
|
||||
- "Statistics helps us:"
|
||||
- "- Understand patterns in data"
|
||||
- "- Make informed decisions"
|
||||
- "- Test hypotheses scientifically"
|
||||
- "- Predict future outcomes"
|
||||
- "- Avoid being fooled by randomness"
|
||||
- ""
|
||||
- "**You'll learn:**"
|
||||
- "✓ Measures of central tendency (mean, median, mode)"
|
||||
- "✓ Measures of spread (range, variance, standard deviation)"
|
||||
- "✓ Probability basics"
|
||||
- "✓ Distributions and what they mean"
|
||||
- "✓ How to interpret data"
|
||||
- ""
|
||||
- "**Real-world applications:**"
|
||||
- "- Medicine (clinical trial results)"
|
||||
- "- Business (sales forecasting)"
|
||||
- "- Sports (player performance)"
|
||||
- "- Science (experimental data)"
|
||||
- "- Everyday decisions (risk assessment)"
|
||||
question: Ready to learn how to understand data and make better decisions?
|
||||
tokens_for_ai: |
|
||||
Accept positive responses as 'ready'.
|
||||
Language preference as 'set_language'.
|
||||
Otherwise 'off_topic'.
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- "Excellent! Let's start with the basics of describing data! 📈"
|
||||
next_section_and_step: central_tendency:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's learn statistics together! Are you ready to begin?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: central_tendency
|
||||
title: Describing Data - Central Tendency
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Center of Data
|
||||
content_blocks:
|
||||
- "## Central Tendency: Finding the 'Middle' 📍"
|
||||
- ""
|
||||
- "When we have a dataset, we often want to describe it with a single number that represents the 'typical' or 'central' value."
|
||||
- ""
|
||||
- "**Three measures of central tendency:**"
|
||||
- ""
|
||||
- "**1. Mean (Average)**"
|
||||
- "- Sum all values and divide by the count"
|
||||
- "- Most commonly used"
|
||||
- "- Sensitive to extreme values (outliers)"
|
||||
- "- Example: Test scores 80, 85, 90, 95 → Mean = (80+85+90+95)/4 = 87.5"
|
||||
- ""
|
||||
- "**2. Median (Middle Value)**"
|
||||
- "- The middle number when data is sorted"
|
||||
- "- Not affected by outliers"
|
||||
- "- Better for skewed data"
|
||||
- "- Example: Salaries $30k, $35k, $40k, $45k, $200k → Median = $40k"
|
||||
- ""
|
||||
- "**3. Mode (Most Frequent)**"
|
||||
- "- The value that appears most often"
|
||||
- "- Useful for categorical data"
|
||||
- "- Can have multiple modes or no mode"
|
||||
- "- Example: Shoe sizes 7, 8, 8, 8, 9, 10 → Mode = 8"
|
||||
- ""
|
||||
- "**When to use which:**"
|
||||
- "- Mean: Normally distributed data without outliers"
|
||||
- "- Median: Skewed data or data with outliers (like income)"
|
||||
- "- Mode: Categorical data or finding most common value"
|
||||
question: "You have exam scores: 60, 70, 75, 80, 85, 90, 95. What is the median score?"
|
||||
tokens_for_ai: |
|
||||
The median is the middle value when sorted.
|
||||
Scores: 60, 70, 75, 80, 85, 90, 95 (7 values)
|
||||
Middle value (4th position) = 80
|
||||
|
||||
Categorize as:
|
||||
- correct: Says 80 or "eighty"
|
||||
- calculated_mean: Says 79.3 or ~79 (they calculated the mean instead)
|
||||
- close: Says 75 or 85 (one position off)
|
||||
- confused: Incorrect answer showing confusion
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Praise them! Explain why 80 is the middle value.
|
||||
- Note that with odd numbers, median is straightforward.
|
||||
|
||||
If they calculated mean:
|
||||
- Good effort but that's the mean!
|
||||
- Explain median is the MIDDLE value when sorted, not the average.
|
||||
|
||||
If close or confused:
|
||||
- Show the sorted list: 60, 70, 75, [80], 85, 90, 95
|
||||
- The middle position (4th out of 7) is 80.
|
||||
buckets:
|
||||
- correct
|
||||
- calculated_mean
|
||||
- close
|
||||
- confused
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect! 80 is the median - the middle value.
|
||||
With 7 values, the 4th position is the center.
|
||||
Median is great because outliers don't affect it!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: central_tendency:step_2
|
||||
calculated_mean:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
That's the mean (average), not the median!
|
||||
Median = middle value when sorted.
|
||||
For 60,70,75,[80],85,90,95 → median is 80.
|
||||
The mean would be all values summed divided by 7.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: central_tendency:step_2
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Close! You're near the middle.
|
||||
Sort the values: 60, 70, 75, [80], 85, 90, 95
|
||||
The exact middle (4th position out of 7) is 80.
|
||||
next_section_and_step: central_tendency:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "The median is the MIDDLE value when you sort the numbers from smallest to largest."
|
||||
- "With 7 values, the 4th number is in the middle."
|
||||
next_section_and_step: central_tendency:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: central_tendency:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's find the median! Sort the scores and identify the middle value."
|
||||
next_section_and_step: central_tendency:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Mean vs Median with Outliers
|
||||
content_blocks:
|
||||
- "## The Power of Median: Handling Outliers 🎯"
|
||||
- ""
|
||||
- "**Why median matters: The salary example**"
|
||||
- ""
|
||||
- "Imagine a small company with 5 employees and their salaries:"
|
||||
- "- Employee A: $40,000"
|
||||
- "- Employee B: $45,000"
|
||||
- "- Employee C: $50,000"
|
||||
- "- Employee D: $55,000"
|
||||
- "- CEO: $500,000"
|
||||
- ""
|
||||
- "**Mean salary:** ($40k + $45k + $50k + $55k + $500k) / 5 = $138,000"
|
||||
- "**Median salary:** $50,000 (the middle value)"
|
||||
- ""
|
||||
- "**Which better represents the 'typical' employee salary?**"
|
||||
- "The median! The mean is dragged up by the CEO's outlier salary."
|
||||
- ""
|
||||
- "**This is why:**"
|
||||
- "- Median home prices are reported (not mean)"
|
||||
- "- Median household income is used (not mean)"
|
||||
- "- Outliers don't distort the median"
|
||||
- ""
|
||||
- "**When one extreme value can mislead, use median!**"
|
||||
question: "A neighborhood has 6 home prices: $200k, $210k, $220k, $230k, $240k, and $2,000k. If someone says 'the average home price is $516k,' why might that be misleading? What would better represent typical home prices?"
|
||||
tokens_for_ai: |
|
||||
They should recognize that:
|
||||
- The $2 million home is an outlier
|
||||
- Mean is misleading ($516k)
|
||||
- Median would be better (between $220k and $230k = $225k)
|
||||
|
||||
Categorize as:
|
||||
- excellent_understanding: Mentions outlier skewing mean, median better
|
||||
- understands_outlier: Recognizes the expensive house is the problem
|
||||
- suggests_median: Says median without explaining why
|
||||
- partial_understanding: On the right track but incomplete
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Validate their understanding of outliers affecting mean!
|
||||
|
||||
Key points:
|
||||
- The $2M home is an outlier (way higher than others)
|
||||
- Mean gets pulled up to $516k (not representative)
|
||||
- Median would be $225k (between 220 and 230) - much more typical
|
||||
- This is why real estate uses median prices!
|
||||
|
||||
Praise their critical thinking about statistics.
|
||||
buckets:
|
||||
- excellent_understanding
|
||||
- understands_outlier
|
||||
- suggests_median
|
||||
- partial_understanding
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Brilliant analysis!
|
||||
Yes - the $2M outlier drags the mean to $516k, misleading!
|
||||
The median ($225k) better represents typical homes.
|
||||
This is exactly why statistics literacy matters!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: spread:step_1
|
||||
understands_outlier:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Exactly! The $2M home is an outlier.
|
||||
It pulls the mean to $516k, but most homes are $200-240k.
|
||||
The median ($225k) would be more representative.
|
||||
Great critical thinking!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: spread:step_1
|
||||
suggests_median:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good instinct - median is better here!
|
||||
Why? The $2M outlier skews the mean to $516k.
|
||||
But the median ($225k) represents the typical home price.
|
||||
Outliers don't affect median - that's its power!
|
||||
next_section_and_step: spread:step_1
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
You're on the right track!
|
||||
The key: one $2M home among $200-240k homes.
|
||||
This outlier pulls mean to $516k (misleading).
|
||||
Median ($225k) better shows typical prices.
|
||||
next_section_and_step: spread:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: central_tendency:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think about: Does $516k accurately represent what most homes in this neighborhood cost?"
|
||||
next_section_and_step: central_tendency:step_2
|
||||
|
||||
- section_id: spread
|
||||
title: Measuring Spread - Variability
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Understanding Variability
|
||||
content_blocks:
|
||||
- "## Spread: How Much Do Values Vary? 📏"
|
||||
- ""
|
||||
- "Central tendency tells us the 'middle,' but doesn't tell the full story."
|
||||
- ""
|
||||
- "**Consider two classes:**"
|
||||
- "- Class A scores: 80, 82, 78, 81, 79 (mean = 80)"
|
||||
- "- Class B scores: 50, 70, 80, 90, 110 (mean = 80)"
|
||||
- ""
|
||||
- "Same mean, VERY different distributions!"
|
||||
- "Class A is consistent. Class B is all over the place."
|
||||
- ""
|
||||
- "**Measures of Spread:**"
|
||||
- ""
|
||||
- "**1. Range**"
|
||||
- "- Maximum value minus minimum value"
|
||||
- "- Simple but sensitive to outliers"
|
||||
- "- Class A: 82 - 78 = 4"
|
||||
- "- Class B: 110 - 50 = 60"
|
||||
- ""
|
||||
- "**2. Variance**"
|
||||
- "- Average of squared differences from mean"
|
||||
- "- Measures how spread out values are"
|
||||
- "- Larger variance = more spread"
|
||||
- ""
|
||||
- "**3. Standard Deviation (SD)**"
|
||||
- "- Square root of variance"
|
||||
- "- Same units as original data (easier to interpret)"
|
||||
- "- Most commonly used measure of spread"
|
||||
- ""
|
||||
- "**Why spread matters:**"
|
||||
- "- Quality control (consistency in manufacturing)"
|
||||
- "- Risk assessment (investment volatility)"
|
||||
- "- Performance evaluation (consistency vs streaky)"
|
||||
- "- Research (reliability of measurements)"
|
||||
question: "Two basketball players both average 20 points per game. Player A's scores: 18, 19, 20, 21, 22. Player B's scores: 5, 10, 20, 30, 35. Which player is more consistent, and why does that matter?"
|
||||
tokens_for_ai: |
|
||||
Player A is more consistent (low spread/variance).
|
||||
Player B is inconsistent/volatile (high spread).
|
||||
|
||||
Look for understanding that:
|
||||
- Player A has consistent performance (small variation)
|
||||
- Player B is unpredictable (large variation)
|
||||
- Consistency matters for reliability/strategy
|
||||
|
||||
Categorize as:
|
||||
- excellent_answer: Identifies Player A as consistent AND explains why it matters
|
||||
- identifies_player_a: Correctly says Player A is more consistent
|
||||
- identifies_inconsistency: Recognizes the difference in variability
|
||||
- basic_answer: Mentions one player without explaining
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Affirm their understanding of consistency/spread!
|
||||
|
||||
Key points:
|
||||
- Player A: very consistent (range 18-22, low variation)
|
||||
- Player B: unpredictable (range 5-35, high variation)
|
||||
- Consistency matters: reliable performance, easier to plan around
|
||||
- Player B might have higher ceiling but less reliable
|
||||
|
||||
Connect to real sports analysis and standard deviation concept.
|
||||
buckets:
|
||||
- excellent_answer
|
||||
- identifies_player_a
|
||||
- identifies_inconsistency
|
||||
- basic_answer
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_answer:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect analysis!
|
||||
Player A: 18-22 (consistent, low spread).
|
||||
Player B: 5-35 (volatile, high spread).
|
||||
Consistency means reliability - you know what to expect!
|
||||
This is what standard deviation measures!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: probability:step_1
|
||||
identifies_player_a:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Correct! Player A is much more consistent.
|
||||
Range: A is 18-22 (4 points), B is 5-35 (30 points!).
|
||||
Low spread = predictable performance.
|
||||
High spread = unpredictable, risky.
|
||||
That's what measuring spread tells us!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: probability:step_1
|
||||
identifies_inconsistency:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good observation about the difference!
|
||||
Player A varies 18-22 (tight, consistent).
|
||||
Player B varies 5-35 (wild, unpredictable).
|
||||
Consistency = reliability. This is why we measure spread!
|
||||
next_section_and_step: probability:step_1
|
||||
basic_answer:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Let's look at the ranges:
|
||||
Player A: 18, 19, 20, 21, 22 (very tight - consistent!)
|
||||
Player B: 5, 10, 20, 30, 35 (all over - inconsistent!)
|
||||
Consistency means you can rely on them. Spread measures this!
|
||||
next_section_and_step: probability:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: spread:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Compare the ranges: Player A (18-22) vs Player B (5-35). Who's more predictable?"
|
||||
next_section_and_step: spread:step_1
|
||||
|
||||
- section_id: probability
|
||||
title: Probability Basics
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Understanding Probability
|
||||
content_blocks:
|
||||
- "## Probability: Quantifying Uncertainty 🎲"
|
||||
- ""
|
||||
- "**What is probability?**"
|
||||
- "A measure of how likely something is to happen."
|
||||
- ""
|
||||
- "**Probability scale:**"
|
||||
- "- 0 = Impossible (0%)"
|
||||
- "- 0.5 = Even chance (50%)"
|
||||
- "- 1 = Certain (100%)"
|
||||
- ""
|
||||
- "**Basic probability formula:**"
|
||||
- "P(event) = (Number of favorable outcomes) / (Total possible outcomes)"
|
||||
- ""
|
||||
- "**Example: Fair die**"
|
||||
- "- P(rolling a 3) = 1/6 ≈ 0.167 (16.7%)"
|
||||
- "- P(rolling even) = 3/6 = 0.5 (50%)"
|
||||
- "- P(rolling 1-6) = 6/6 = 1 (100%)"
|
||||
- ""
|
||||
- "**Key concepts:**"
|
||||
- ""
|
||||
- "**Independent events:**"
|
||||
- "- One doesn't affect the other"
|
||||
- "- Coin flips, die rolls"
|
||||
- "- P(heads then heads) = 0.5 × 0.5 = 0.25"
|
||||
- ""
|
||||
- "**Dependent events:**"
|
||||
- "- One affects the probability of the other"
|
||||
- "- Drawing cards without replacement"
|
||||
- ""
|
||||
- "**Common misconceptions:**"
|
||||
- "- Gambler's fallacy: 'It's due!' (No - each event is independent)"
|
||||
- "- Hot hand fallacy: Past streaks predict future (they don't in random events)"
|
||||
question: "You flip a fair coin 5 times and get heads every time. What's the probability the 6th flip is heads? Why?"
|
||||
tokens_for_ai: |
|
||||
Correct answer: 50% or 0.5 or 1/2
|
||||
|
||||
Key understanding: Each flip is INDEPENDENT.
|
||||
Past flips don't affect future flips.
|
||||
|
||||
Common wrong answer: "It's more likely to be tails" (gambler's fallacy)
|
||||
|
||||
Categorize as:
|
||||
- correct_with_reasoning: Says 50% AND explains independence
|
||||
- correct_answer: Says 50% without full explanation
|
||||
- gamblers_fallacy: Says tails is more likely because "it's due"
|
||||
- pattern_thinking: Thinks the pattern will continue
|
||||
- confused: Other incorrect reasoning
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Excellent! Each flip is independent.
|
||||
- Past results don't affect future flips.
|
||||
- The coin has no "memory" - always 50/50.
|
||||
|
||||
If gambler's fallacy:
|
||||
- Common misconception! This is the "gambler's fallacy."
|
||||
- Each flip is independent - past doesn't affect future.
|
||||
- It's still 50/50, even after 100 heads in a row!
|
||||
- The coin doesn't "owe" you tails.
|
||||
|
||||
Explain independence clearly.
|
||||
buckets:
|
||||
- correct_with_reasoning
|
||||
- correct_answer
|
||||
- gamblers_fallacy
|
||||
- pattern_thinking
|
||||
- confused
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_with_reasoning:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect understanding!
|
||||
Each coin flip is independent - past doesn't affect future.
|
||||
The coin has no memory. Always 50/50!
|
||||
You've avoided the gambler's fallacy - great!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: distributions:step_1
|
||||
correct_answer:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Correct - still 50%!
|
||||
Why? Each flip is INDEPENDENT.
|
||||
Past flips don't affect future flips.
|
||||
The coin doesn't "remember" or "balance out."
|
||||
Great job avoiding the gambler's fallacy!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: distributions:step_1
|
||||
gamblers_fallacy:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Common misconception! This is the "gambler's fallacy."
|
||||
Each flip is INDEPENDENT - the coin has no memory.
|
||||
Past flips don't affect future flips.
|
||||
It's still 50/50, even after 1000 heads!
|
||||
The coin doesn't "owe" you tails.
|
||||
next_section_and_step: probability:step_1
|
||||
pattern_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
The streak feels meaningful, but it's not!
|
||||
Each flip is independent - 50/50 every time.
|
||||
Past results don't predict future with fair coins.
|
||||
Random sequences often have "patterns" but they're meaningless.
|
||||
next_section_and_step: probability:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Key concept: INDEPENDENCE"
|
||||
- "Each coin flip is independent - past flips don't affect future flips."
|
||||
- "A fair coin always has 50% chance of heads, regardless of history."
|
||||
next_section_and_step: probability:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: probability:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think: Does the coin 'remember' previous flips? Are they independent events?"
|
||||
next_section_and_step: probability:step_1
|
||||
|
||||
- section_id: distributions
|
||||
title: Understanding Distributions
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Normal Distribution
|
||||
content_blocks:
|
||||
- "## The Normal Distribution: Nature's Pattern 📊"
|
||||
- ""
|
||||
- "**The bell curve (normal distribution):**"
|
||||
- "The most important distribution in statistics!"
|
||||
- ""
|
||||
- "**Characteristics:**"
|
||||
- "- Symmetric, bell-shaped"
|
||||
- "- Mean = Median = Mode (at the center)"
|
||||
- "- Most data near the mean"
|
||||
- "- Tails extend infinitely (but rarely reach extremes)"
|
||||
- ""
|
||||
- "**The 68-95-99.7 Rule (Empirical Rule):**"
|
||||
- "- 68% of data within 1 standard deviation of mean"
|
||||
- "- 95% of data within 2 standard deviations"
|
||||
- "- 99.7% of data within 3 standard deviations"
|
||||
- ""
|
||||
- "**Example: IQ scores**"
|
||||
- "- Mean = 100, Standard Deviation = 15"
|
||||
- "- 68% of people: IQ between 85-115"
|
||||
- "- 95% of people: IQ between 70-130"
|
||||
- "- 99.7% of people: IQ between 55-145"
|
||||
- ""
|
||||
- "**Why normal distribution matters:**"
|
||||
- "- Many natural phenomena follow it (height, measurement errors)"
|
||||
- "- Central Limit Theorem (averages tend toward normal)"
|
||||
- "- Foundation for many statistical tests"
|
||||
- "- Allows predictions and probability calculations"
|
||||
- ""
|
||||
- "**Real-world examples:**"
|
||||
- "- Test scores, heights, blood pressure, measurement errors"
|
||||
question: "SAT scores are normally distributed with mean 1000 and standard deviation 200. Using the 68-95-99.7 rule, approximately what percentage of students score between 800 and 1200?"
|
||||
tokens_for_ai: |
|
||||
800 to 1200 is mean (1000) ± 1 standard deviation (200).
|
||||
68% of data falls within 1 SD of the mean.
|
||||
|
||||
Correct answer: 68% (or approximately 68%, or about 2/3)
|
||||
|
||||
Categorize as:
|
||||
- correct: Says 68% or approximately 68%
|
||||
- close: Says 66% or 70% (reasonably close)
|
||||
- says_95: Says 95% (confused 1 SD with 2 SD)
|
||||
- unclear_reasoning: Wrong answer showing confusion
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Excellent! 800-1200 is 1000 ± 200 (1 SD).
|
||||
- 68% of data within 1 SD of mean.
|
||||
- You've mastered the empirical rule!
|
||||
|
||||
If says 95%:
|
||||
- Close reasoning! But 95% is for 2 SDs.
|
||||
- 800-1200 is only 1 SD (200 points) from mean.
|
||||
- 1 SD = 68%, 2 SDs = 95%, 3 SDs = 99.7%
|
||||
|
||||
Explain the calculation clearly.
|
||||
buckets:
|
||||
- correct
|
||||
- close
|
||||
- says_95
|
||||
- unclear_reasoning
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect! 800-1200 is mean ± 1 SD.
|
||||
1 SD = 68% of data.
|
||||
You understand the empirical rule!
|
||||
This is fundamental for interpreting normal distributions!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: conclusion:step_1
|
||||
close:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Very close! The exact answer is 68%.
|
||||
800-1200 = 1000 ± 200 (1 standard deviation).
|
||||
The 68-95-99.7 rule: 68% within 1 SD.
|
||||
Great understanding of the concept!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: conclusion:step_1
|
||||
says_95:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
You're thinking of the right rule, but different range!
|
||||
95% is for 2 standard deviations (600-1400).
|
||||
800-1200 is only 1 SD (200 points) from mean.
|
||||
1 SD = 68%, 2 SDs = 95%, 3 SDs = 99.7%
|
||||
next_section_and_step: distributions:step_1
|
||||
unclear_reasoning:
|
||||
content_blocks:
|
||||
- "Use the 68-95-99.7 rule:"
|
||||
- "800-1200 is the mean (1000) ± 200"
|
||||
- "200 is 1 standard deviation"
|
||||
- "68% of data falls within 1 SD of the mean"
|
||||
next_section_and_step: distributions:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: distributions:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Calculate: How many standard deviations is 800-1200 from the mean (1000)?"
|
||||
next_section_and_step: distributions:step_1
|
||||
|
||||
- section_id: conclusion
|
||||
title: Statistics Mastery
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Applying Statistical Thinking
|
||||
content_blocks:
|
||||
- "## Congratulations, Statistician! 🎓📊"
|
||||
- ""
|
||||
- "**You've mastered the fundamentals!**"
|
||||
- ""
|
||||
- "**What you've learned:**"
|
||||
- "✓ Central Tendency (mean, median, mode)"
|
||||
- "✓ When to use median vs mean (outliers!)"
|
||||
- "✓ Measures of spread (range, variance, standard deviation)"
|
||||
- "✓ Probability and independence"
|
||||
- "✓ The normal distribution and 68-95-99.7 rule"
|
||||
- ""
|
||||
- "**Real-world statistical thinking:**"
|
||||
- ""
|
||||
- "**Evaluating claims:**"
|
||||
- "- 'Average salary is $100k!' → Check for outliers, ask for median"
|
||||
- "- 'Significant difference!' → What's the sample size?"
|
||||
- "- 'This trend proves...' → Correlation ≠ causation"
|
||||
- ""
|
||||
- "**Making decisions:**"
|
||||
- "- Compare means AND spreads (consistency matters!)"
|
||||
- "- Understand probability (avoid gambler's fallacy)"
|
||||
- "- Consider distributions (is it normal? skewed?)"
|
||||
- ""
|
||||
- "**Critical thinking:**"
|
||||
- "- Always ask: What's the sample size?"
|
||||
- "- Question: How was data collected?"
|
||||
- "- Consider: What's being measured exactly?"
|
||||
- "- Look for: Potential biases or confounding factors"
|
||||
question: "How will you use statistical thinking in your daily life? Give an example of where understanding statistics could help you make better decisions."
|
||||
tokens_for_ai: |
|
||||
This is a reflection question.
|
||||
|
||||
Look for application of concepts learned:
|
||||
- Evaluating claims with mean/median awareness
|
||||
- Understanding probability in decisions
|
||||
- Recognizing variability/consistency
|
||||
- Critical thinking about data
|
||||
|
||||
Categorize as:
|
||||
- excellent_application: Specific example showing deep understanding
|
||||
- practical_example: Good real-world application
|
||||
- general_reflection: Acknowledges usefulness
|
||||
- brief_response: Short but relevant
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Provide encouraging, personalized feedback!
|
||||
|
||||
Validate their example if they give one.
|
||||
Add suggestions for statistical thinking in daily life:
|
||||
- Evaluating news/research claims
|
||||
- Financial decisions (investments, insurance)
|
||||
- Health decisions (understanding medical stats)
|
||||
- Sports analysis
|
||||
- Weather forecasts (probability!)
|
||||
|
||||
Celebrate their completion of Statistics 101!
|
||||
buckets:
|
||||
- excellent_application
|
||||
- practical_example
|
||||
- general_reflection
|
||||
- brief_response
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_application:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Fantastic example showing real understanding!
|
||||
Reference their specific application.
|
||||
Emphasize how statistical literacy empowers better decisions.
|
||||
Encourage continued critical thinking with data!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
practical_example:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great practical thinking!
|
||||
Acknowledge their example.
|
||||
Statistics helps us cut through misleading claims.
|
||||
You now have tools to think critically about data!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
general_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good reflection!
|
||||
Statistics is everywhere - news, health, money, sports.
|
||||
You can now question claims and understand probability.
|
||||
Keep thinking statistically!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
brief_response:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Thank you for completing Statistics 101!
|
||||
You've gained powerful tools for understanding data.
|
||||
Use them to make informed decisions and question claims!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: conclusion:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Reflect on: How could understanding mean, median, probability, and distributions help you in everyday decisions?"
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,740 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate understanding of basic game theory concepts.
|
||||
|
||||
Consider:
|
||||
- Grasp of strategic interaction
|
||||
- Understanding of Nash equilibrium
|
||||
- Recognition of dominant strategies
|
||||
- Ability to analyze simple games
|
||||
- Application to real-world scenarios
|
||||
|
||||
Provide clear explanations with examples.
|
||||
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Game Theory
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Strategic Thinking
|
||||
content_blocks:
|
||||
- "# Game Theory 101: The Science of Strategy 🎮🧠"
|
||||
- ""
|
||||
- "**Welcome to game theory!**"
|
||||
- ""
|
||||
- "Game theory is the study of strategic interaction - how people make decisions when their outcomes depend on others' choices."
|
||||
- ""
|
||||
- "**Not just for games:**"
|
||||
- "- Business competition (pricing, market entry)"
|
||||
- "- International relations (nuclear deterrence, trade)"
|
||||
- "- Biology (evolution, animal behavior)"
|
||||
- "- Economics (auctions, bargaining)"
|
||||
- "- Everyday life (traffic, cooperation)"
|
||||
- ""
|
||||
- "**You'll learn:**"
|
||||
- "✓ The Prisoner's Dilemma (cooperation vs self-interest)"
|
||||
- "✓ Nash Equilibrium (stable strategies)"
|
||||
- "✓ Dominant strategies (always-best moves)"
|
||||
- "✓ Zero-sum vs positive-sum games"
|
||||
- "✓ How to analyze strategic situations"
|
||||
- ""
|
||||
- "**Real applications:**"
|
||||
- "- Why cartels are unstable"
|
||||
- "- Why arms races happen"
|
||||
- "- When cooperation emerges"
|
||||
- "- How auctions should be designed"
|
||||
question: Ready to learn how to think strategically about interactive decisions?
|
||||
tokens_for_ai: |
|
||||
Accept positive responses as 'ready'.
|
||||
Language preference as 'set_language'.
|
||||
Otherwise 'off_topic'.
|
||||
buckets:
|
||||
- ready
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
ready:
|
||||
content_blocks:
|
||||
- "Excellent! Let's start with the most famous game in game theory! 🎯"
|
||||
next_section_and_step: prisoners_dilemma:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's learn strategic thinking together! Ready to begin?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: prisoners_dilemma
|
||||
title: The Prisoner's Dilemma
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Classic Dilemma
|
||||
content_blocks:
|
||||
- "## The Prisoner's Dilemma: Cooperation vs Self-Interest 🚔"
|
||||
- ""
|
||||
- "**The Scenario:**"
|
||||
- ""
|
||||
- "Two criminals are arrested and interrogated separately. The prosecutor offers each the same deal:"
|
||||
- ""
|
||||
- "**If you both stay silent:**"
|
||||
- "- Each gets 1 year in prison (light sentence, lack of evidence)"
|
||||
- ""
|
||||
- "**If you betray your partner but they stay silent:**"
|
||||
- "- You go free (0 years)"
|
||||
- "- Your partner gets 3 years"
|
||||
- ""
|
||||
- "**If you both betray each other:**"
|
||||
- "- Each gets 2 years"
|
||||
- ""
|
||||
- "**Payoff matrix (years in prison - lower is better):**"
|
||||
- ""
|
||||
- "```"
|
||||
- " Player B"
|
||||
- " Silent Betray"
|
||||
- "Player A Silent (-1,-1) (-3,0)"
|
||||
- " Betray (0,-3) (-2,-2)"
|
||||
- "```"
|
||||
- ""
|
||||
- "**The dilemma:**"
|
||||
- "- **Collectively best:** Both stay silent (-1 each)"
|
||||
- "- **Individually rational:** Both betray (-2 each)"
|
||||
- ""
|
||||
- "**Why betray dominates:**"
|
||||
- "- If partner stays silent: Betray gets you 0 vs 1 year (betray better!)"
|
||||
- "- If partner betrays: Betray gets you 2 vs 3 years (betray better!)"
|
||||
- "- No matter what partner does, betraying is better for YOU"
|
||||
- ""
|
||||
- "**The tragedy:** Both act rationally, both end up worse off (-2 each) than if they'd cooperated (-1 each)!"
|
||||
question: "You're playing prisoner's dilemma once with a stranger you'll never meet again. What should you do from a purely self-interested perspective, and why?"
|
||||
tokens_for_ai: |
|
||||
Correct answer: Betray (or defect/confess)
|
||||
|
||||
Reasoning: Betraying is a DOMINANT STRATEGY
|
||||
- Dominates silence regardless of what partner does
|
||||
- If partner silent: 0 years better than 1 year
|
||||
- If partner betrays: 2 years better than 3 years
|
||||
|
||||
Look for understanding of dominant strategy.
|
||||
|
||||
Categorize as:
|
||||
- correct_with_reasoning: Says betray AND explains dominant strategy
|
||||
- correct_answer: Says betray without full explanation
|
||||
- says_cooperate: Says stay silent (cooperative but not rational in one-shot)
|
||||
- game_theory_aware: Mentions dilemma nature even if wrong choice
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Excellent! Betraying is the DOMINANT STRATEGY.
|
||||
- No matter what the other player does, betraying is better for YOU.
|
||||
- This is rational but leads to both getting -2 instead of -1.
|
||||
- That's the tragedy of the Prisoner's Dilemma!
|
||||
|
||||
If says cooperate:
|
||||
- Noble but not strategically optimal in a one-shot game!
|
||||
- Betraying DOMINATES: better outcome regardless of partner's choice.
|
||||
- In one-shot games with strangers, defection is predicted.
|
||||
- (Later we'll see when cooperation can emerge in repeated games!)
|
||||
|
||||
Explain dominant strategy concept clearly.
|
||||
buckets:
|
||||
- correct_with_reasoning
|
||||
- correct_answer
|
||||
- says_cooperate
|
||||
- game_theory_aware
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_with_reasoning:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect strategic analysis!
|
||||
Betraying is the DOMINANT STRATEGY - always better for you.
|
||||
Even though both cooperating would be better collectively (-1 each),
|
||||
individual rationality leads to mutual defection (-2 each).
|
||||
This is the fundamental insight of game theory!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
correct_answer:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Correct! Betraying is the rational choice.
|
||||
Why? It's a DOMINANT STRATEGY.
|
||||
No matter what your partner does, betraying gives YOU a better outcome.
|
||||
If they stay silent: 0 < 1. If they betray: 2 < 3.
|
||||
This individual rationality creates the dilemma!
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
says_cooperate:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Cooperation would be great if you could trust them!
|
||||
But from pure self-interest in a ONE-SHOT game:
|
||||
Betraying DOMINATES staying silent.
|
||||
If they're silent: 0 years (betray) beats 1 year (silent).
|
||||
If they betray: 2 years (betray) beats 3 years (silent).
|
||||
Betraying is always better for YOU - that's the dilemma!
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
game_theory_aware:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
You sense the dilemma!
|
||||
From pure self-interest: betraying DOMINATES.
|
||||
It's better for you no matter what they do.
|
||||
Both thinking this way → both defect → both get -2.
|
||||
Could've gotten -1 each if they cooperated. That's the tragedy!
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: prisoners_dilemma:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think strategically: What gives YOU the best outcome regardless of what your partner does?"
|
||||
next_section_and_step: prisoners_dilemma:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Real-World Dilemmas
|
||||
content_blocks:
|
||||
- "## Prisoner's Dilemma Everywhere! 🌍"
|
||||
- ""
|
||||
- "The Prisoner's Dilemma structure appears constantly:"
|
||||
- ""
|
||||
- "**Business cartels:**"
|
||||
- "- Cooperate: Keep prices high (both profit)"
|
||||
- "- Defect: Undercut price (steal market share)"
|
||||
- "- Problem: Undercutting is always tempting!"
|
||||
- "- Result: Cartels are unstable"
|
||||
- ""
|
||||
- "**Arms races:**"
|
||||
- "- Cooperate: Don't build weapons (both save money)"
|
||||
- "- Defect: Build weapons (get advantage if opponent doesn't)"
|
||||
- "- Problem: Building weapons dominates"
|
||||
- "- Result: Costly arms races"
|
||||
- ""
|
||||
- "**Environmental pollution:**"
|
||||
- "- Cooperate: Reduce emissions (collective good)"
|
||||
- "- Defect: Pollute freely (save costs)"
|
||||
- "- Problem: Individual incentive to pollute"
|
||||
- "- Result: Tragedy of the commons"
|
||||
- ""
|
||||
- "**Doping in sports:**"
|
||||
- "- Cooperate: Stay clean (fair competition)"
|
||||
- "- Defect: Dope (gain advantage)"
|
||||
- "- Problem: If others dope, you must too to compete"
|
||||
- "- Result: Widespread doping"
|
||||
- ""
|
||||
- "**The pattern:**"
|
||||
- "Individual rationality → collectively bad outcome"
|
||||
question: "Can you think of another real-world situation that has Prisoner's Dilemma structure? Describe what cooperation and defection look like."
|
||||
tokens_for_ai: |
|
||||
Look for recognition of the PD structure:
|
||||
- Two or more parties
|
||||
- Temptation to defect while others cooperate
|
||||
- Mutual defection worse than mutual cooperation
|
||||
- Defection is individually rational
|
||||
|
||||
Examples: cheating in class, tax evasion, littering, free-riding,
|
||||
overfishing, etc.
|
||||
|
||||
Categorize as:
|
||||
- excellent_example: Clear PD structure with cooperation/defection explained
|
||||
- good_example: Recognizes PD structure
|
||||
- vague_example: Right idea but unclear
|
||||
- not_quite_pd: Example doesn't fit structure
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If they identify a good example:
|
||||
- Validate it! Explain how it fits PD structure.
|
||||
- Point out: cooperation better collectively, defection individually rational.
|
||||
- This recognition helps understand so many social problems!
|
||||
|
||||
If example doesn't quite fit:
|
||||
- Acknowledge the thinking.
|
||||
- Explain what makes something a PD: mutual defection < mutual cooperation < defection while others cooperate.
|
||||
- Offer a clearer example.
|
||||
|
||||
Celebrate their application of game theory!
|
||||
buckets:
|
||||
- excellent_example
|
||||
- good_example
|
||||
- vague_example
|
||||
- not_quite_pd
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_example:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Brilliant example!
|
||||
Reference their specific example and confirm the PD structure.
|
||||
Point out: cooperation collectively better, but defection individually tempting.
|
||||
This is why so many social problems are hard to solve!
|
||||
Game theory helps us recognize these structures!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
good_example:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great example!
|
||||
Confirm it has PD structure: defection tempting, but mutual defection worse.
|
||||
This pattern is everywhere once you see it!
|
||||
Understanding the structure helps design solutions (regulations, incentives, reputation).
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
vague_example:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good thinking! Clarify how their example fits:
|
||||
Cooperation = ? (collectively better)
|
||||
Defection = ? (individually tempting)
|
||||
Help them sharpen the structure identification.
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
not_quite_pd:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Interesting example but not quite Prisoner's Dilemma structure.
|
||||
PD needs: mutual cooperation > mutual defection, but defection dominates.
|
||||
Their example might be a different game structure.
|
||||
Acknowledge their thinking, explain the distinction.
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Think of situations where everyone would be better off cooperating, but individuals are tempted to cheat."
|
||||
next_section_and_step: prisoners_dilemma:step_2
|
||||
|
||||
- section_id: nash_equilibrium
|
||||
title: Nash Equilibrium
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Stable Strategies
|
||||
content_blocks:
|
||||
- "## Nash Equilibrium: The Stability Concept 🎯"
|
||||
- ""
|
||||
- "**Named after John Nash (Nobel Prize, 1994)**"
|
||||
- ""
|
||||
- "**Definition:**"
|
||||
- "A Nash Equilibrium is a set of strategies where no player can improve their outcome by unilaterally changing their strategy."
|
||||
- ""
|
||||
- "**In simpler terms:**"
|
||||
- "Everyone is playing their best response to what others are doing. No one wants to deviate."
|
||||
- ""
|
||||
- "**In Prisoner's Dilemma:**"
|
||||
- "Both betraying is a Nash Equilibrium!"
|
||||
- "- If A betrays, B's best response is betray (2 < 3 years)"
|
||||
- "- If B betrays, A's best response is betray (2 < 3 years)"
|
||||
- "- Neither wants to switch to silence unilaterally"
|
||||
- ""
|
||||
- "**Key insight:**"
|
||||
- "Nash Equilibrium ≠ Best outcome for everyone"
|
||||
- "It's just stable (self-enforcing)"
|
||||
- ""
|
||||
- "**Example: Coordination Game**"
|
||||
- ""
|
||||
- "Two friends picking where to meet:"
|
||||
- "```"
|
||||
- " Friend B"
|
||||
- " Coffee Bar"
|
||||
- "Friend A Coffee (2,2) (0,0)"
|
||||
- " Bar (0,0) (1,1)"
|
||||
- "```"
|
||||
- ""
|
||||
- "**Two Nash Equilibria:**"
|
||||
- "1. Both go to Coffee (2,2)"
|
||||
- "2. Both go to Bar (1,1)"
|
||||
- ""
|
||||
- "Meeting anywhere > missing each other!"
|
||||
- "Coordination problems have multiple equilibria."
|
||||
question: "In a game where two drivers approach an intersection, each can either Stop or Go. If both Go, they crash (payoff -10 each). If one Stops and one Goes, the goer gets +1 and the stopper gets 0. If both Stop, they're delayed (payoff -1 each). What are the Nash Equilibrium outcomes?"
|
||||
tokens_for_ai: |
|
||||
Payoff matrix:
|
||||
Driver B
|
||||
Stop Go
|
||||
Driver A Stop (-1,-1) (0,+1)
|
||||
Go (+1,0) (-10,-10)
|
||||
|
||||
Nash Equilibria: (Stop, Go) and (Go, Stop)
|
||||
- If A stops, B's best response is Go
|
||||
- If B goes, A's best response is Stop
|
||||
- And vice versa for (Go, Stop)
|
||||
|
||||
NOT Nash Equilibrium:
|
||||
- (Stop, Stop): Either could improve by switching to Go
|
||||
- (Go, Go): Both would improve by switching to Stop
|
||||
|
||||
Look for identification of the two equilibria.
|
||||
|
||||
Categorize as:
|
||||
- correct_both: Identifies both (Stop,Go) and (Go,Stop)
|
||||
- identifies_one: Gets one of the two equilibria
|
||||
- identifies_pattern: Recognizes one stops, one goes
|
||||
- says_both_stop: Says (Stop,Stop) - incorrect
|
||||
- confused: Other answers
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Correct equilibria: (Stop, Go) and (Go, Stop)
|
||||
|
||||
If correct:
|
||||
- Excellent! Two Nash Equilibria where one stops, one goes.
|
||||
- Neither wants to unilaterally change.
|
||||
- This is like traffic lights solving coordination!
|
||||
|
||||
If says both stop:
|
||||
- That seems safe but it's NOT Nash Equilibrium!
|
||||
- If both stop, either could switch to Go and get +1 instead of -1.
|
||||
- Nash requires no one wants to unilaterally deviate.
|
||||
|
||||
Explain why the two asymmetric outcomes are stable.
|
||||
buckets:
|
||||
- correct_both
|
||||
- identifies_one
|
||||
- identifies_pattern
|
||||
- says_both_stop
|
||||
- confused
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_both:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect! Two Nash Equilibria: (Stop,Go) and (Go,Stop).
|
||||
In each, no driver wants to unilaterally change.
|
||||
Both stopping is NOT equilibrium - either would want to go!
|
||||
This coordination problem is solved by traffic lights in reality!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
identifies_one:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good! You found one equilibrium.
|
||||
But there's symmetry - also a Nash Equilibrium where roles reverse!
|
||||
Both (Stop,Go) and (Go,Stop) are stable.
|
||||
In each, neither wants to unilaterally change.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
identifies_pattern:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Right idea - one stops, one goes!
|
||||
Specifically: (Stop,Go) and (Go,Stop) are both Nash Equilibria.
|
||||
Neither driver wants to change their strategy given the other's.
|
||||
This is a coordination game solved by conventions (like traffic lights!).
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
says_both_stop:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Seems safe, but NOT Nash Equilibrium!
|
||||
At (Stop,Stop), either driver could switch to Go:
|
||||
Get +1 instead of -1 while other stays stopped.
|
||||
Nash requires no one wants to deviate.
|
||||
The equilibria are (Stop,Go) and (Go,Stop).
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Check each outcome: Can any player improve by switching?"
|
||||
- "Nash Equilibrium: No player wants to unilaterally change strategy"
|
||||
- "Hint: One driver stops, one goes (two ways to do this)"
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Find outcomes where neither driver would want to change their choice given what the other is doing."
|
||||
next_section_and_step: nash_equilibrium:step_1
|
||||
|
||||
- section_id: dominant_strategies
|
||||
title: Dominant Strategies
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Always-Best Strategies
|
||||
content_blocks:
|
||||
- "## Dominant Strategies: No-Brainer Moves 💪"
|
||||
- ""
|
||||
- "**Definition:**"
|
||||
- "A dominant strategy is one that's best regardless of what other players do."
|
||||
- ""
|
||||
- "**If you have a dominant strategy, PLAY IT!**"
|
||||
- ""
|
||||
- "**In Prisoner's Dilemma:**"
|
||||
- "Betraying is a dominant strategy for both players."
|
||||
- "- Better if opponent stays silent: 0 < 1"
|
||||
- "- Better if opponent betrays: 2 < 3"
|
||||
- "- Always better!"
|
||||
- ""
|
||||
- "**Dominant Strategy Equilibrium:**"
|
||||
- "When all players have dominant strategies, the outcome is certain!"
|
||||
- "- Everyone plays their dominant strategy"
|
||||
- "- This is always a Nash Equilibrium"
|
||||
- "- But Nash Equilibrium doesn't always involve dominant strategies"
|
||||
- ""
|
||||
- "**Example without dominant strategies:**"
|
||||
- ""
|
||||
- "Rock-Paper-Scissors:"
|
||||
- "- No strategy is always best"
|
||||
- "- Best strategy depends on opponent's choice"
|
||||
- "- Optimal: Randomize (mixed strategy)"
|
||||
- ""
|
||||
- "**Why dominant strategies matter:**"
|
||||
- "- Simplify analysis (easy to predict)"
|
||||
- "- Stable and robust"
|
||||
- "- Used in mechanism design (incentive compatibility)"
|
||||
question: "A company must choose High Price or Low Price. If both choose High, each earns $100. If both choose Low, each earns $50. If one chooses Low and other High, the low pricer earns $120 and the high pricer earns $20. Does either company have a dominant strategy? If so, what is it?"
|
||||
tokens_for_ai: |
|
||||
Payoff matrix:
|
||||
Company B
|
||||
High Low
|
||||
Company A High (100,100) (20,120)
|
||||
Low (120,20) (50,50)
|
||||
|
||||
For Company A:
|
||||
- If B plays High: Low gives 120 > High gives 100 → Low better
|
||||
- If B plays Low: Low gives 50 > High gives 20 → Low better
|
||||
- Low DOMINATES High
|
||||
|
||||
Same logic for Company B.
|
||||
Both have dominant strategy: Low Price
|
||||
|
||||
Look for recognition that Low dominates High.
|
||||
|
||||
Categorize as:
|
||||
- correct_both_low: Says Low is dominant strategy for both
|
||||
- says_low: Identifies Low without full explanation
|
||||
- says_high: Says High (incorrect - not dominant)
|
||||
- says_no_dominant: Says no dominant strategy exists
|
||||
- unclear: Confused answer
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Correct: Low is dominant strategy for BOTH companies.
|
||||
|
||||
If correct:
|
||||
- Excellent! Low dominates High for both.
|
||||
- If opponent prices High: 120 > 100 (Low better)
|
||||
- If opponent prices Low: 50 > 20 (Low better)
|
||||
- Result: Both price low, earn 50 each (could've earned 100 each!)
|
||||
- This is another Prisoner's Dilemma structure!
|
||||
|
||||
If wrong:
|
||||
- Check each scenario.
|
||||
- Show that Low always outperforms High regardless of opponent.
|
||||
- Explain this leads to (Low,Low) equilibrium.
|
||||
|
||||
Connect to PD structure.
|
||||
buckets:
|
||||
- correct_both_low
|
||||
- says_low
|
||||
- says_high
|
||||
- says_no_dominant
|
||||
- unclear
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
correct_both_low:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect analysis!
|
||||
Low DOMINATES High for both companies.
|
||||
No matter what opponent does, Low is better.
|
||||
Result: (Low,Low) = $50 each.
|
||||
If they could cooperate: (High,High) = $100 each!
|
||||
This is Prisoner's Dilemma in business form!
|
||||
metadata_add:
|
||||
score: "n+2"
|
||||
concepts_mastered: "n+1"
|
||||
next_section_and_step: conclusion:step_1
|
||||
says_low:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Correct! Low is the dominant strategy.
|
||||
Why? Check both scenarios:
|
||||
If opponent prices High: 120 (Low) > 100 (High)
|
||||
If opponent prices Low: 50 (Low) > 20 (High)
|
||||
Always better! This is another PD structure.
|
||||
metadata_add:
|
||||
score: "n+1"
|
||||
next_section_and_step: conclusion:step_1
|
||||
says_high:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
High would be great if both could commit!
|
||||
But it's NOT dominant. Check:
|
||||
If opponent prices Low: 20 (High) < 120 (Low)
|
||||
Low is better regardless of opponent.
|
||||
This is why cartels are unstable!
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
says_no_dominant:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Actually, there IS a dominant strategy!
|
||||
Compare for Company A:
|
||||
- If B plays High: Low(120) > High(100)
|
||||
- If B plays Low: Low(50) > High(20)
|
||||
Low is always better! Same for Company B.
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
unclear:
|
||||
content_blocks:
|
||||
- "For dominant strategy, check: Is one choice ALWAYS better than the other?"
|
||||
- "Compare Low vs High when opponent plays High, then when opponent plays Low"
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "For each company, which strategy is better regardless of what the opponent does?"
|
||||
next_section_and_step: dominant_strategies:step_1
|
||||
|
||||
- section_id: conclusion
|
||||
title: Game Theory Foundations
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Strategic Thinking
|
||||
content_blocks:
|
||||
- "## Congratulations, Game Theorist! 🎓🎮"
|
||||
- ""
|
||||
- "**You've mastered the fundamentals!**"
|
||||
- ""
|
||||
- "**What you've learned:**"
|
||||
- "✓ Prisoner's Dilemma (cooperation vs self-interest)"
|
||||
- "✓ Nash Equilibrium (stable strategy profiles)"
|
||||
- "✓ Dominant strategies (always-best moves)"
|
||||
- "✓ How to analyze strategic situations"
|
||||
- "✓ Why individually rational choices can lead to bad collective outcomes"
|
||||
- ""
|
||||
- "**Key insights:**"
|
||||
- "- Strategic thinking requires considering others' incentives"
|
||||
- "- Equilibrium ≠ optimal (Prisoner's Dilemma!)"
|
||||
- "- Dominant strategies simplify prediction"
|
||||
- "- Coordination problems have multiple equilibria"
|
||||
- "- Institutions and repeated play can enable cooperation"
|
||||
- ""
|
||||
- "**Real-world applications:**"
|
||||
- "- Understanding why cartels fail"
|
||||
- "- Recognizing arms race dynamics"
|
||||
- "- Designing better mechanisms (auctions, voting)"
|
||||
- "- Building institutions that align incentives"
|
||||
- ""
|
||||
- "**Next steps:**"
|
||||
- "- Game Theory 201: Mixed strategies and repeated games"
|
||||
- "- Look for strategic interactions in daily life"
|
||||
- "- Think about how to align individual and collective interests"
|
||||
question: "How has learning game theory changed how you think about strategic situations? Give an example where you might apply these concepts."
|
||||
tokens_for_ai: |
|
||||
This is a reflection question.
|
||||
|
||||
Look for:
|
||||
- Recognition of strategic interdependence
|
||||
- Understanding that others' incentives matter
|
||||
- Application to real situations
|
||||
- Appreciation of conflict between individual/collective rationality
|
||||
|
||||
Categorize as:
|
||||
- excellent_reflection: Insightful application showing deep understanding
|
||||
- practical_application: Good real-world example
|
||||
- general_reflection: Acknowledges usefulness
|
||||
- brief_response: Short but relevant
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
Provide encouraging feedback!
|
||||
|
||||
Validate their example/reflection.
|
||||
Emphasize key takeaway: think about others' incentives!
|
||||
Game theory helps predict behavior and design better systems.
|
||||
|
||||
Mention Game Theory 201 for deeper concepts.
|
||||
Celebrate their foundational understanding!
|
||||
buckets:
|
||||
- excellent_reflection
|
||||
- practical_application
|
||||
- general_reflection
|
||||
- brief_response
|
||||
- set_language
|
||||
- off_topic
|
||||
transitions:
|
||||
excellent_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Fantastic insight!
|
||||
Reference their example specifically.
|
||||
You now think strategically about interdependent decisions!
|
||||
This foundation enables understanding mechanism design, auctions, bargaining.
|
||||
Ready for Game Theory 201 when you are!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
practical_application:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great application!
|
||||
Acknowledge their example.
|
||||
Game theory is everywhere once you start looking!
|
||||
Understanding incentives helps predict and influence behavior.
|
||||
Excellent work mastering the fundamentals!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
general_reflection:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good reflection!
|
||||
The core lesson: always consider others' incentives.
|
||||
Strategic interactions are everywhere - business, politics, daily life.
|
||||
You've built a strong foundation in game theory!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
brief_response:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Thank you for completing Game Theory 101!
|
||||
You've learned to think strategically about interactive decisions.
|
||||
These concepts underpin economics, politics, and much more!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: conclusion:step_1
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Reflect: How might understanding incentives and strategic interaction help you in real-world situations?"
|
||||
next_section_and_step: conclusion:step_1
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Welcome to Game Theory 201
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Beyond Pure Strategies
|
||||
content_blocks:
|
||||
- "# Game Theory 201: Mixed Strategies & Repeated Games 🎲🔄"
|
||||
- "**Building on Game Theory 101!**"
|
||||
- ""
|
||||
- "**You'll learn:**"
|
||||
- "✓ Mixed strategies (randomization)"
|
||||
- "✓ When and why to randomize"
|
||||
- "✓ Repeated games (shadow of the future)"
|
||||
- "✓ How cooperation emerges"
|
||||
- "✓ Tit-for-Tat and winning strategies"
|
||||
question: Ready to explore more advanced strategic concepts?
|
||||
tokens_for_ai: Accept positive as 'ready', language as 'set_language', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready:
|
||||
next_section_and_step: mixed_strategies:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: mixed_strategies
|
||||
title: Mixed Strategies
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Randomization as Strategy
|
||||
content_blocks:
|
||||
- "## Mixed Strategies: The Power of Unpredictability 🎲"
|
||||
- ""
|
||||
- "**Pure vs Mixed Strategies:**"
|
||||
- "- Pure: Always play the same action"
|
||||
- "- Mixed: Randomize between actions with specific probabilities"
|
||||
- ""
|
||||
- "**Rock-Paper-Scissors:**"
|
||||
- "No pure strategy works - opponent can exploit patterns!"
|
||||
- "Solution: Randomize equally (1/3, 1/3, 1/3)"
|
||||
- ""
|
||||
- "**Penalty Kicks in Soccer:**"
|
||||
- "- Kicker: Left or Right?"
|
||||
- "- Goalie: Dive Left or Right?"
|
||||
- "- Must be unpredictable!"
|
||||
- "- Data shows pros randomize ~50/50"
|
||||
- ""
|
||||
- "**When to use mixed strategies:**"
|
||||
- "- No dominant pure strategy"
|
||||
- "- Opponent can exploit predictability"
|
||||
- "- Matching Pennies, Hide and Seek, Security games"
|
||||
question: In Rock-Paper-Scissors, why can't you always play Rock? What happens if you're predictable?
|
||||
tokens_for_ai: |
|
||||
Should recognize: predictability allows exploitation.
|
||||
If always Rock, opponent plays Paper and wins.
|
||||
Categorize: understands_exploitation, recognizes_problem, vague, set_language, off_topic
|
||||
buckets: [understands_exploitation, recognizes_problem, vague, set_language, off_topic]
|
||||
transitions:
|
||||
understands_exploitation:
|
||||
ai_feedback: {tokens_for_ai: "Perfect! Predictability = exploitation. Opponent plays Paper, you lose. Randomization prevents exploitation!"}
|
||||
metadata_add: {score: "n+2"}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
recognizes_problem:
|
||||
ai_feedback: {tokens_for_ai: "Right! If you always play Rock, smart opponent plays Paper every time. Randomization is the solution!"}
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
vague:
|
||||
ai_feedback: {tokens_for_ai: "If you always play Rock, opponent learns and always plays Paper. You lose every time! Must randomize."}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: mixed_strategies:step_1
|
||||
off_topic:
|
||||
next_section_and_step: mixed_strategies:step_1
|
||||
|
||||
- section_id: repeated_games
|
||||
title: Repeated Games
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: The Shadow of the Future
|
||||
content_blocks:
|
||||
- "## Repeated Games: When Tomorrow Matters 🔄"
|
||||
- ""
|
||||
- "**One-shot vs Repeated:**"
|
||||
- "- One-shot PD: Defect dominates"
|
||||
- "- Repeated PD: Cooperation can emerge!"
|
||||
- ""
|
||||
- "**Why repetition changes everything:**"
|
||||
- "- Reputation matters"
|
||||
- "- Retaliation is possible"
|
||||
- "- Future gains can outweigh immediate temptation"
|
||||
- ""
|
||||
- "**Tit-for-Tat Strategy:**"
|
||||
- "1. Start with cooperation"
|
||||
- "2. Then copy opponent's previous move"
|
||||
- "- Nice (never defects first)"
|
||||
- "- Retaliatory (punishes defection)"
|
||||
- "- Forgiving (returns to cooperation)"
|
||||
- "- Clear (easy to understand)"
|
||||
- ""
|
||||
- "**Axelrod's Tournament:**"
|
||||
- "Tit-for-Tat won! Simplest, most effective."
|
||||
- "Beat complex strategies through cooperation + accountability"
|
||||
question: Why can cooperation emerge in repeated Prisoner's Dilemma but not in one-shot games?
|
||||
tokens_for_ai: |
|
||||
Key insight: future interactions create incentive to cooperate.
|
||||
Fear of retaliation, value of reputation, shadow of future.
|
||||
Categorize: excellent_understanding, identifies_repetition, partial, set_language, off_topic
|
||||
buckets: [excellent_understanding, identifies_repetition, partial, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_understanding:
|
||||
ai_feedback: {tokens_for_ai: "Brilliant! Future interactions change incentives. Retaliation possible, reputation matters. Short-term gain < long-term cooperation!"}
|
||||
metadata_add: {score: "n+2", activity_completed: "true"}
|
||||
identifies_repetition:
|
||||
ai_feedback: {tokens_for_ai: "Exactly! Repeated games allow punishment and reward. Cooperation becomes rational when future matters!"}
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
partial:
|
||||
ai_feedback: {tokens_for_ai: "Right direction! Key: future interactions create accountability. Can punish defectors, reward cooperators. Changes incentives!"}
|
||||
metadata_add: {activity_completed: "true"}
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: repeated_games:step_1
|
||||
off_topic:
|
||||
metadata_add: {activity_completed: "true"}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Game Theory 301
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Cooperative Games
|
||||
content_blocks:
|
||||
- "# Game Theory 301: Cooperative Games & Coalitions 🤝"
|
||||
- "**Beyond zero-sum thinking!**"
|
||||
- "✓ Cooperative game theory"
|
||||
- "✓ Coalition formation"
|
||||
- "✓ Shapley value (fair division)"
|
||||
- "✓ Core stability"
|
||||
question: Ready to learn about cooperation and coalition building?
|
||||
tokens_for_ai: Accept positive as 'ready', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready: {next_section_and_step: "coalitions:step_1"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
|
||||
- section_id: coalitions
|
||||
title: Coalition Formation
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Coalition Building
|
||||
content_blocks:
|
||||
- "## Coalitions: Strength in Numbers 💪"
|
||||
- ""
|
||||
- "**Characteristic function form:**"
|
||||
- "v(Coalition) = value coalition can guarantee"
|
||||
- ""
|
||||
- "**Example: Three companies**"
|
||||
- "- Alone: A=$10M, B=$15M, C=$20M"
|
||||
- "- A+B together: $30M"
|
||||
- "- A+C together: $35M"
|
||||
- "- B+C together: $40M"
|
||||
- "- All three: $60M"
|
||||
- ""
|
||||
- "**Questions:**"
|
||||
- "- Which coalition forms?"
|
||||
- "- How to split the gains fairly?"
|
||||
- ""
|
||||
- "**Shapley Value:**"
|
||||
- "Fair division based on marginal contributions"
|
||||
- "Each player gets average of their marginal value across all orderings"
|
||||
question: If three players create $60M together but would create $0 individually, how should they split the gains to be fair?
|
||||
tokens_for_ai: |
|
||||
Equal split ($20M each) is one fair answer.
|
||||
Shapley value would calculate based on marginal contributions.
|
||||
Categorize: says_equal, considers_contributions, unclear, set_language, off_topic
|
||||
buckets: [says_equal, considers_contributions, unclear, set_language, off_topic]
|
||||
transitions:
|
||||
says_equal:
|
||||
ai_feedback: {tokens_for_ai: "Equal split is fair! Each contributed equally to coalition. Shapley value would give $20M each too."}
|
||||
metadata_add: {score: "n+2", activity_completed: "true"}
|
||||
considers_contributions:
|
||||
ai_feedback: {tokens_for_ai: "Good thinking about contributions! With symmetric players, equal split is the Shapley value."}
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
unclear:
|
||||
ai_feedback: {tokens_for_ai: "Fair approach: equal split since all contributed equally. Each gets $20M. This is the Shapley value!"}
|
||||
metadata_add: {activity_completed: "true"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "coalitions:step_1"}
|
||||
off_topic: {metadata_add: {activity_completed: "true"}}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Game Theory 401
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Information Games
|
||||
content_blocks:
|
||||
- "# Game Theory 401: Information Asymmetry 🔍"
|
||||
- "**When players have different information!**"
|
||||
- "✓ Signaling (revealing information)"
|
||||
- "✓ Screening (eliciting information)"
|
||||
- "✓ Adverse selection"
|
||||
- "✓ Moral hazard"
|
||||
question: Ready to explore strategic information problems?
|
||||
tokens_for_ai: Accept positive as 'ready', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready: {next_section_and_step: "signaling:step_1"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
|
||||
- section_id: signaling
|
||||
title: Signaling & Screening
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Credible Signals
|
||||
content_blocks:
|
||||
- "## Signaling: Credibly Revealing Information 📢"
|
||||
- ""
|
||||
- "**The problem:**"
|
||||
- "You have valuable information others don't"
|
||||
- "How to credibly communicate it?"
|
||||
- ""
|
||||
- "**Education as Signal:**"
|
||||
- "- Degree signals ability/work ethic"
|
||||
- "- Costly to obtain (time, money, effort)"
|
||||
- "- Harder for low-ability workers"
|
||||
- "- Separates high from low types"
|
||||
- ""
|
||||
- "**Key: Must be costly for low types!**"
|
||||
- "Otherwise everyone signals, signal loses meaning"
|
||||
- ""
|
||||
- "**Other examples:**"
|
||||
- "- Warranties (signal quality)"
|
||||
- "- Money-back guarantees"
|
||||
- "- Certifications"
|
||||
- "- Peacock's tail (biological signaling)"
|
||||
- ""
|
||||
- "**Adverse Selection:**"
|
||||
- "When information asymmetry leads to market failure"
|
||||
- "Example: Used car market (lemons problem)"
|
||||
question: Why must a signal be costly to be credible? What happens if it's cheap for everyone?
|
||||
tokens_for_ai: |
|
||||
Key insight: if signal is cheap for all types, everyone signals.
|
||||
Signal loses informational value (pooling).
|
||||
Must be differentially costly to separate types.
|
||||
Categorize: excellent_understanding, understands_cost, partial, set_language, off_topic
|
||||
buckets: [excellent_understanding, understands_cost, partial, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_understanding:
|
||||
ai_feedback: {tokens_for_ai: "Perfect! If everyone can signal cheaply, everyone does. Signal becomes meaningless. Must be differentially costly to separate types!"}
|
||||
metadata_add: {score: "n+2", activity_completed: "true"}
|
||||
understands_cost:
|
||||
ai_feedback: {tokens_for_ai: "Exactly! Cheap signals lose meaning. Everyone would claim to be high quality. Cost creates separation!"}
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
partial:
|
||||
ai_feedback: {tokens_for_ai: "Right direction! If signal is free, everyone sends it. Becomes noise. Cost differentiates high from low quality!"}
|
||||
metadata_add: {activity_completed: "true"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "signaling:step_1"}
|
||||
off_topic: {metadata_add: {activity_completed: "true"}}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Game Theory 501
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Design the Game
|
||||
content_blocks:
|
||||
- "# Game Theory 501: Mechanism Design 🏗️"
|
||||
- "**Reverse game theory: Design the game itself!**"
|
||||
- "✓ Mechanism design (reverse game theory)"
|
||||
- "✓ Auction theory"
|
||||
- "✓ Voting theory"
|
||||
- "✓ Incentive compatibility"
|
||||
question: Ready to learn how to design strategic systems?
|
||||
tokens_for_ai: Accept positive as 'ready', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready: {next_section_and_step: "mechanism_design:step_1"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"}
|
||||
|
||||
- section_id: mechanism_design
|
||||
title: Designing Strategic Systems
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Incentive Engineering
|
||||
content_blocks:
|
||||
- "## Mechanism Design: Engineering Incentives 🎯"
|
||||
- ""
|
||||
- "**The challenge:**"
|
||||
- "Design rules so self-interested players produce desired outcomes"
|
||||
- ""
|
||||
- "**Revelation Principle:**"
|
||||
- "Focus on mechanisms where truth-telling is optimal"
|
||||
- "'Incentive compatible' mechanisms"
|
||||
- ""
|
||||
- "**Vickrey Auction (2nd-price sealed-bid):**"
|
||||
- "- Everyone submits sealed bid"
|
||||
- "- Highest bidder wins"
|
||||
- "- Pays 2nd-highest bid"
|
||||
- ""
|
||||
- "**Why brilliant:**"
|
||||
- "- Dominant strategy: Bid your true value!"
|
||||
- "- Overbidding risks paying too much"
|
||||
- "- Underbidding risks losing when you'd profit"
|
||||
- "- Truthful bidding is optimal"
|
||||
- ""
|
||||
- "**Applications:**"
|
||||
- "- eBay (proxy bidding)"
|
||||
- "- Google AdWords"
|
||||
- "- Organ donation matching"
|
||||
- "- Spectrum auctions"
|
||||
question: In a Vickrey auction, why is bidding your true value the dominant strategy?
|
||||
tokens_for_ai: |
|
||||
Key insight: You pay 2nd price, not your bid.
|
||||
Overbidding risks paying more than value.
|
||||
Underbidding risks losing profitable wins.
|
||||
True value bidding is optimal.
|
||||
Categorize: excellent_explanation, understands_truthful, partial, set_language, off_topic
|
||||
buckets: [excellent_explanation, understands_truthful, partial, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_explanation:
|
||||
ai_feedback: {tokens_for_ai: "Perfect! Since you pay 2nd price, not your bid, bidding true value is dominant. Can't improve by lying! This is mechanism design genius!"}
|
||||
metadata_add: {score: "n+2", activity_completed: "true"}
|
||||
understands_truthful:
|
||||
ai_feedback: {tokens_for_ai: "Exactly! Paying 2nd price means truthful bidding is optimal. Over/under bidding can only hurt you. Brilliant design!"}
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
partial:
|
||||
ai_feedback: {tokens_for_ai: "Right idea! Key: you pay 2nd price. Bidding true value dominates - lying can't help, might hurt. This is mechanism design!"}
|
||||
metadata_add: {activity_completed: "true"}
|
||||
set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "mechanism_design:step_1"}
|
||||
off_topic: {metadata_add: {activity_completed: "true"}}
|
||||
|
|
@ -1,509 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate the student's ability to implement game theory concepts in Python.
|
||||
|
||||
Consider:
|
||||
- Correct Python syntax
|
||||
- Understanding of game theory concepts
|
||||
- Code logic and structure
|
||||
- Use of appropriate data structures
|
||||
- Ability to translate concepts to code
|
||||
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Programming Game Theory in Python
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Code Meets Strategy
|
||||
content_blocks:
|
||||
- "# Game Theory Programming with Python 🐍🎮"
|
||||
- ""
|
||||
- "**Learn Python by implementing game theory!**"
|
||||
- ""
|
||||
- "You'll learn to:"
|
||||
- "✓ Represent games as data structures"
|
||||
- "✓ Implement payoff matrices"
|
||||
- "✓ Code Prisoner's Dilemma simulations"
|
||||
- "✓ Find Nash Equilibria programmatically"
|
||||
- "✓ Simulate repeated games with strategies"
|
||||
- ""
|
||||
- "**Prerequisites:**"
|
||||
- "- Basic Python knowledge (variables, functions, loops)"
|
||||
- "- Understanding of basic game theory (Nash Equilibrium, Prisoner's Dilemma)"
|
||||
- ""
|
||||
- "**Why this matters:**"
|
||||
- "- Learn to model strategic situations"
|
||||
- "- Practice data structures (dictionaries, lists)"
|
||||
- "- Build simulations and experiments"
|
||||
- "- Apply theory to real code"
|
||||
question: Ready to implement game theory in Python?
|
||||
tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready:
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: payoff_matrix
|
||||
title: Representing Games as Data
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Payoff Matrix Structure
|
||||
content_blocks:
|
||||
- "## Representing Payoff Matrices in Python 📊"
|
||||
- ""
|
||||
- "**The challenge:**"
|
||||
- "How do we represent a 2-player game in code?"
|
||||
- ""
|
||||
- "**Game structure:**"
|
||||
- "- Two players (Row, Column)"
|
||||
- "- Each has strategies (actions)"
|
||||
- "- Each outcome has payoffs for both players"
|
||||
- ""
|
||||
- "**Conceptual approach:**"
|
||||
- "A payoff matrix maps strategy pairs to payoff tuples"
|
||||
- "- Input: (player1_strategy, player2_strategy)"
|
||||
- "- Output: (player1_payoff, player2_payoff)"
|
||||
- ""
|
||||
- "**Data structure choice:**"
|
||||
- "Python dictionaries are perfect!"
|
||||
- "- Keys: tuples of strategy pairs"
|
||||
- "- Values: tuples of payoffs"
|
||||
- ""
|
||||
- "**Example concept (Prisoner's Dilemma):**"
|
||||
- "```"
|
||||
- "Strategies: 'cooperate' or 'defect'"
|
||||
- "Payoffs: (player1_years, player2_years)"
|
||||
- "If both cooperate: (-1, -1)"
|
||||
- "If both defect: (-2, -2)"
|
||||
- "If one defects while other cooperates: (0, -3) or (-3, 0)"
|
||||
- "```"
|
||||
question: "Write Python code to create a dictionary representing the Prisoner's Dilemma payoff matrix. Use strategy pairs as keys (tuples like ('cooperate', 'defect')) and payoff tuples as values."
|
||||
tokens_for_ai: |
|
||||
Looking for Python dictionary with:
|
||||
- Keys: tuples of (player1_strategy, player2_strategy)
|
||||
- Values: tuples of (player1_payoff, player2_payoff)
|
||||
- Four outcomes: (C,C), (C,D), (D,C), (D,D)
|
||||
|
||||
Correct payoffs (years in prison):
|
||||
- ('cooperate', 'cooperate'): (-1, -1)
|
||||
- ('cooperate', 'defect'): (-3, 0)
|
||||
- ('defect', 'cooperate'): (0, -3)
|
||||
- ('defect', 'defect'): (-2, -2)
|
||||
|
||||
Categorize as:
|
||||
- correct: Proper dictionary with all 4 outcomes and correct payoffs
|
||||
- correct_structure: Right structure, minor payoff errors
|
||||
- uses_dictionary: Uses dict but wrong format
|
||||
- wrong_approach: Different data structure
|
||||
- needs_help: Very basic or confused
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Excellent! Dictionary maps strategy pairs to payoffs perfectly.
|
||||
- This structure makes lookups easy.
|
||||
- Show how to access: payoff_matrix[('cooperate', 'defect')] → (-3, 0)
|
||||
|
||||
If structure right but payoffs wrong:
|
||||
- Great structure! But check payoffs:
|
||||
- Both cooperate: (-1, -1) - best mutual outcome
|
||||
- Both defect: (-2, -2) - mutual punishment
|
||||
- One defects: (0, -3) or (-3, 0) - betrayal
|
||||
|
||||
If wrong approach:
|
||||
- Show correct dictionary structure with example.
|
||||
- Explain why dict with tuple keys is elegant for this.
|
||||
buckets: [correct, correct_structure, uses_dictionary, wrong_approach, needs_help, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect implementation!
|
||||
Your dictionary elegantly maps strategy pairs to payoffs.
|
||||
Access is simple: matrix[('cooperate', 'defect')] gives (-3, 0).
|
||||
This structure scales to more complex games!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
correct_structure:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great structure! Minor payoff correction needed:
|
||||
- Both cooperate: (-1, -1)
|
||||
- Both defect: (-2, -2)
|
||||
- One defects: betrayer gets 0, cooperator gets -3
|
||||
Show the corrected version.
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
uses_dictionary:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good use of dictionary!
|
||||
For game matrices, use tuple keys:
|
||||
payoff_matrix = {
|
||||
('cooperate', 'cooperate'): (-1, -1),
|
||||
('cooperate', 'defect'): (-3, 0),
|
||||
...
|
||||
}
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
wrong_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Python dictionaries with tuple keys work best!
|
||||
Example format:
|
||||
game = {('action1', 'action2'): (payoff1, payoff2)}
|
||||
This allows easy lookup of any strategy combination.
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
needs_help:
|
||||
content_blocks:
|
||||
- "Start with: game = {}"
|
||||
- "Add entries like: ('cooperate', 'cooperate'): (-1, -1)"
|
||||
- "You need 4 entries total for all strategy combinations"
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
off_topic:
|
||||
next_section_and_step: payoff_matrix:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Querying the Matrix
|
||||
content_blocks:
|
||||
- "## Using the Payoff Matrix 🔍"
|
||||
- ""
|
||||
- "**Now that you have a payoff matrix, let's use it!**"
|
||||
- ""
|
||||
- "**Task:** Write a function that determines outcomes"
|
||||
- ""
|
||||
- "**Function requirements:**"
|
||||
- "- Name: `get_payoffs`"
|
||||
- "- Parameters: `payoff_matrix`, `player1_action`, `player2_action`"
|
||||
- "- Returns: tuple of (player1_payoff, player2_payoff)"
|
||||
- ""
|
||||
- "**What the function does:**"
|
||||
- "Looks up the payoffs for the given strategy combination"
|
||||
- ""
|
||||
- "**Think about:**"
|
||||
- "- How do you access dictionary values?"
|
||||
- "- How do you create the lookup key from the two actions?"
|
||||
question: "Write a Python function called `get_payoffs` that takes a payoff matrix dictionary and two player actions, then returns the payoff tuple for that strategy combination."
|
||||
tokens_for_ai: |
|
||||
Looking for function that:
|
||||
- Takes 3 parameters: payoff_matrix (dict), player1_action, player2_action
|
||||
- Creates tuple key: (player1_action, player2_action)
|
||||
- Returns: payoff_matrix[(player1_action, player2_action)]
|
||||
|
||||
Acceptable variations:
|
||||
- def get_payoffs(matrix, p1, p2): return matrix[(p1, p2)]
|
||||
- def get_payoffs(payoff_matrix, action1, action2): ...
|
||||
|
||||
Categorize as:
|
||||
- correct: Proper function with correct lookup
|
||||
- correct_logic: Right idea, minor syntax issues
|
||||
- missing_tuple: Tries to lookup without creating tuple key
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect! Your function correctly creates a tuple key and looks it up.
|
||||
- Example: get_payoffs(game, 'cooperate', 'defect') → (-3, 0)
|
||||
- Clean, simple, and reusable!
|
||||
|
||||
If correct logic but syntax issues:
|
||||
- Right approach! Small syntax fix needed.
|
||||
- Show corrected version.
|
||||
- Explain the fix.
|
||||
|
||||
If missing tuple:
|
||||
- Remember: dictionary keys are tuples!
|
||||
- Need to create (player1_action, player2_action) first.
|
||||
- Then look it up in the matrix.
|
||||
buckets: [correct, correct_logic, missing_tuple, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent function!
|
||||
Your code cleanly creates the tuple key and returns the payoffs.
|
||||
This abstraction makes game simulation much easier.
|
||||
You can now query any strategy combination!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: simulation:step_1
|
||||
correct_logic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great logic! Minor syntax adjustment:
|
||||
Show corrected function.
|
||||
Explain what was fixed and why it matters.
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: simulation:step_1
|
||||
missing_tuple:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Close! Don't forget to create the tuple key:
|
||||
|
||||
def get_payoffs(payoff_matrix, p1_action, p2_action):
|
||||
key = (p1_action, p2_action)
|
||||
return payoff_matrix[key]
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
confused:
|
||||
content_blocks:
|
||||
- "A function that takes the matrix and both actions"
|
||||
- "Creates a tuple from the two actions: (action1, action2)"
|
||||
- "Uses that tuple to look up the payoffs in the dictionary"
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
off_topic:
|
||||
next_section_and_step: payoff_matrix:step_2
|
||||
|
||||
- section_id: simulation
|
||||
title: Simulating Strategic Interactions
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: One-Shot Game Simulator
|
||||
content_blocks:
|
||||
- "## Simulating Game Outcomes 🎲"
|
||||
- ""
|
||||
- "**Building a simple game simulator**"
|
||||
- ""
|
||||
- "**Requirements:**"
|
||||
- "- Function name: `play_game`"
|
||||
- "- Parameters: `payoff_matrix`, `strategy1`, `strategy2`"
|
||||
- "- Should call your `get_payoffs` function"
|
||||
- "- Print the outcome in a readable format"
|
||||
- "- Return the payoffs"
|
||||
- ""
|
||||
- "**Example output format:**"
|
||||
- "```"
|
||||
- "Player 1 chose: cooperate"
|
||||
- "Player 2 chose: defect"
|
||||
- "Payoffs: Player 1 = -3, Player 2 = 0"
|
||||
- "```"
|
||||
- ""
|
||||
- "**Conceptual flow:**"
|
||||
- "1. Get payoffs using your get_payoffs function"
|
||||
- "2. Display what each player chose"
|
||||
- "3. Display the resulting payoffs"
|
||||
- "4. Return the payoffs for further use"
|
||||
question: "Write a `play_game` function that simulates one round of a game, prints the outcome, and returns the payoffs. Use your `get_payoffs` function from earlier."
|
||||
tokens_for_ai: |
|
||||
Looking for function that:
|
||||
- Calls get_payoffs(payoff_matrix, strategy1, strategy2)
|
||||
- Prints player choices and payoffs
|
||||
- Returns the payoff tuple
|
||||
|
||||
Should show understanding of:
|
||||
- Function composition (using get_payoffs)
|
||||
- Print statements for output
|
||||
- Returning values
|
||||
|
||||
Categorize as:
|
||||
- correct: Complete function with print and return
|
||||
- missing_print: Has logic but doesn't print
|
||||
- missing_return: Prints but doesn't return
|
||||
- correct_concept: Right idea, minor issues
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Excellent! Your simulator uses function composition nicely.
|
||||
- The print statements make outcomes clear.
|
||||
- Returning payoffs allows chaining simulations.
|
||||
- This is how game theory research is done programmatically!
|
||||
|
||||
If missing print:
|
||||
- Good logic! Add print statements to show:
|
||||
- What each player chose
|
||||
- The resulting payoffs
|
||||
- Makes debugging and understanding easier!
|
||||
|
||||
If missing return:
|
||||
- Good output! But also return the payoffs.
|
||||
- This lets you use the function in larger simulations.
|
||||
- return payoffs at the end.
|
||||
|
||||
Show complete example if needed.
|
||||
buckets: [correct, missing_print, missing_return, correct_concept, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Perfect simulator!
|
||||
You've built function composition (play_game uses get_payoffs).
|
||||
Print statements provide visibility.
|
||||
Return value enables further analysis.
|
||||
You're ready for repeated game simulation!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
missing_print:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Good structure! Add print statements:
|
||||
print(f"Player 1 chose: {strategy1}")
|
||||
print(f"Player 2 chose: {strategy2}")
|
||||
print(f"Payoffs: Player 1 = {payoffs[0]}, Player 2 = {payoffs[1]}")
|
||||
Makes the simulation observable!
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
missing_return:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great output! Just add:
|
||||
return payoffs
|
||||
This lets you accumulate results over many rounds!
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: repeated_games:step_1
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Right approach! Small improvements:
|
||||
Show polished version.
|
||||
Explain the refinements.
|
||||
next_section_and_step: repeated_games:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Your function should:"
|
||||
- "1. Call get_payoffs to get the payoffs"
|
||||
- "2. Print what each player chose"
|
||||
- "3. Print the payoffs"
|
||||
- "4. Return the payoffs tuple"
|
||||
next_section_and_step: simulation:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: simulation:step_1
|
||||
off_topic:
|
||||
next_section_and_step: simulation:step_1
|
||||
|
||||
- section_id: repeated_games
|
||||
title: Repeated Game Strategies
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Tit-for-Tat Strategy
|
||||
content_blocks:
|
||||
- "## Implementing Strategic Behavior 🔄"
|
||||
- ""
|
||||
- "**The Tit-for-Tat Strategy:**"
|
||||
- "1. Start with cooperation"
|
||||
- "2. Then copy opponent's previous move"
|
||||
- ""
|
||||
- "**Implementation challenge:**"
|
||||
- "Create a function that implements Tit-for-Tat logic"
|
||||
- ""
|
||||
- "**Function requirements:**"
|
||||
- "- Name: `tit_for_tat`"
|
||||
- "- Parameter: `opponent_last_move` (or None for first move)"
|
||||
- "- Returns: 'cooperate' or 'defect'"
|
||||
- ""
|
||||
- "**Logic:**"
|
||||
- "- If it's the first move (opponent_last_move is None): return 'cooperate'"
|
||||
- "- Otherwise: return whatever the opponent played last"
|
||||
- ""
|
||||
- "**Why this is powerful:**"
|
||||
- "- Nice (starts with cooperation)"
|
||||
- "- Retaliatory (punishes defection)"
|
||||
- "- Forgiving (returns to cooperation)"
|
||||
- "- Simple to understand and implement"
|
||||
question: "Write a `tit_for_tat` function that takes an opponent's last move (or None for first round) and returns the appropriate strategy according to Tit-for-Tat logic."
|
||||
tokens_for_ai: |
|
||||
Correct logic:
|
||||
- If opponent_last_move is None: return 'cooperate'
|
||||
- Else: return opponent_last_move
|
||||
|
||||
Acceptable implementations:
|
||||
- Simple if/else
|
||||
- Ternary operator
|
||||
- Return with 'or' default
|
||||
|
||||
Categorize as:
|
||||
- correct: Proper Tit-for-Tat logic
|
||||
- correct_logic: Right idea, minor syntax
|
||||
- wrong_first_move: Doesn't handle None case
|
||||
- always_cooperates: Ignores opponent's move
|
||||
- confused: Wrong logic
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect Tit-for-Tat implementation!
|
||||
- First move: cooperate (nice)
|
||||
- After: copy opponent (retaliatory & forgiving)
|
||||
- This won Axelrod's tournament!
|
||||
- Show usage example.
|
||||
|
||||
If correct logic:
|
||||
- Great logic! Small syntax refinement:
|
||||
- Show corrected version.
|
||||
|
||||
If wrong first move:
|
||||
- Remember: Tit-for-Tat starts with cooperation!
|
||||
- Check if opponent_last_move is None (first round).
|
||||
- If None, return 'cooperate'.
|
||||
|
||||
If always cooperates:
|
||||
- You need to copy the opponent's move!
|
||||
- After first round, return opponent_last_move.
|
||||
- That's what makes it "tit for tat"!
|
||||
buckets: [correct, correct_logic, wrong_first_move, always_cooperates, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent Tit-for-Tat implementation!
|
||||
Your code captures the strategy perfectly:
|
||||
- Nice: starts with cooperation
|
||||
- Retaliatory: copies opponent's defection
|
||||
- Forgiving: copies opponent's return to cooperation
|
||||
This simple strategy is remarkably effective!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"}
|
||||
correct_logic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great logic! Minor polish:
|
||||
Show refined version.
|
||||
Your understanding of the strategy is solid!
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
wrong_first_move:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Almost there! Handle the first move:
|
||||
|
||||
def tit_for_tat(opponent_last_move):
|
||||
if opponent_last_move is None:
|
||||
return 'cooperate' # Be nice first
|
||||
return opponent_last_move # Then copy
|
||||
next_section_and_step: repeated_games:step_1
|
||||
always_cooperates:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
That's "always cooperate," not Tit-for-Tat!
|
||||
Tit-for-Tat must COPY the opponent's last move.
|
||||
Only the FIRST move is automatically cooperate.
|
||||
next_section_and_step: repeated_games:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Tit-for-Tat logic:"
|
||||
- "1. First move (when opponent_last_move is None): cooperate"
|
||||
- "2. All other moves: copy opponent's last move"
|
||||
- "Use an if statement to check for None"
|
||||
next_section_and_step: repeated_games:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: repeated_games:step_1
|
||||
off_topic:
|
||||
metadata_add: {activity_completed: "true"}
|
||||
|
|
@ -1,528 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate the student's ability to implement game theory concepts in C.
|
||||
|
||||
Consider:
|
||||
- Correct C syntax
|
||||
- Proper use of structs and pointers
|
||||
- Memory management awareness
|
||||
- Understanding of game theory concepts
|
||||
- Code structure and organization
|
||||
|
||||
sections:
|
||||
- section_id: introduction
|
||||
title: Programming Game Theory in C
|
||||
steps:
|
||||
- step_id: welcome
|
||||
title: Systems Programming Meets Strategy
|
||||
content_blocks:
|
||||
- "# Game Theory Programming with C ⚙️🎮"
|
||||
- ""
|
||||
- "**Learn C by implementing game theory!**"
|
||||
- ""
|
||||
- "You'll learn to:"
|
||||
- "✓ Define game structures with structs"
|
||||
- "✓ Use 2D arrays for payoff matrices"
|
||||
- "✓ Work with pointers and memory"
|
||||
- "✓ Implement strategy functions"
|
||||
- "✓ Build game simulators in C"
|
||||
- ""
|
||||
- "**Prerequisites:**"
|
||||
- "- Basic C knowledge (variables, functions, arrays)"
|
||||
- "- Understanding of basic game theory concepts"
|
||||
- ""
|
||||
- "**Why C for game theory:**"
|
||||
- "- Performance for large simulations"
|
||||
- "- Memory efficiency"
|
||||
- "- Understanding low-level implementation"
|
||||
- "- Foundation for understanding algorithms"
|
||||
question: Ready to implement game theory in C?
|
||||
tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic'
|
||||
buckets: [ready, set_language, off_topic]
|
||||
transitions:
|
||||
ready:
|
||||
next_section_and_step: structures:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
off_topic:
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: introduction:welcome
|
||||
|
||||
- section_id: structures
|
||||
title: Defining Game Structures
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Payoff Structure
|
||||
content_blocks:
|
||||
- "## Representing Payoffs in C 📐"
|
||||
- ""
|
||||
- "**The challenge:**"
|
||||
- "How do we represent a payoff (two player outcomes) in C?"
|
||||
- ""
|
||||
- "**Conceptual requirement:**"
|
||||
- "Each outcome has TWO values:"
|
||||
- "- Player 1's payoff"
|
||||
- "- Player 2's payoff"
|
||||
- ""
|
||||
- "**C solution: struct**"
|
||||
- "A struct groups related data together"
|
||||
- ""
|
||||
- "**What your struct needs:**"
|
||||
- "- A name (like 'Payoff' or 'Outcome')"
|
||||
- "- Two integer fields for the two payoffs"
|
||||
- ""
|
||||
- "**Struct syntax reminder:**"
|
||||
- "```"
|
||||
- "struct StructName {"
|
||||
- " type field1;"
|
||||
- " type field2;"
|
||||
- "};"
|
||||
- "```"
|
||||
question: "Define a C struct called 'Payoff' that contains two integer fields: 'player1' and 'player2' for storing each player's payoff."
|
||||
tokens_for_ai: |
|
||||
Looking for struct definition with:
|
||||
- Name: Payoff (or similar like Outcome, GameResult)
|
||||
- Two int fields for the two player payoffs
|
||||
|
||||
Correct examples:
|
||||
struct Payoff {
|
||||
int player1;
|
||||
int player2;
|
||||
};
|
||||
|
||||
or
|
||||
|
||||
typedef struct {
|
||||
int p1;
|
||||
int p2;
|
||||
} Payoff;
|
||||
|
||||
Categorize as:
|
||||
- correct: Valid struct with two int fields
|
||||
- correct_concept: Right idea, minor syntax
|
||||
- missing_fields: Struct but wrong/missing fields
|
||||
- no_struct: Doesn't use struct
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect struct definition!
|
||||
- Your struct groups the two payoffs together.
|
||||
- Now you can create: struct Payoff outcome;
|
||||
- Access: outcome.player1 = -1; outcome.player2 = -1;
|
||||
|
||||
If correct concept:
|
||||
- Right idea! Small syntax adjustment:
|
||||
- Show corrected version.
|
||||
- Explain the fix.
|
||||
|
||||
If missing fields:
|
||||
- Remember: need TWO integer fields
|
||||
- One for player1's payoff
|
||||
- One for player2's payoff
|
||||
|
||||
If no struct:
|
||||
- C structs group related data!
|
||||
- Show example struct format.
|
||||
buckets: [correct, correct_concept, missing_fields, no_struct, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent struct definition!
|
||||
Your Payoff struct elegantly groups both players' outcomes.
|
||||
Usage: struct Payoff p = {-1, -2}; or p.player1 = 0;
|
||||
This is the foundation for representing game outcomes!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: structures:step_2
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great concept! Minor syntax refinement:
|
||||
Show corrected struct.
|
||||
Explain the adjustment made.
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: structures:step_2
|
||||
missing_fields:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Need two int fields!
|
||||
|
||||
struct Payoff {
|
||||
int player1;
|
||||
int player2;
|
||||
};
|
||||
|
||||
This stores both players' payoffs together.
|
||||
next_section_and_step: structures:step_1
|
||||
no_struct:
|
||||
content_blocks:
|
||||
- "Use a struct to group the two payoffs:"
|
||||
- "struct Payoff { ... };"
|
||||
- "Include two int fields inside the braces"
|
||||
next_section_and_step: structures:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Define a struct with:"
|
||||
- "- Name: Payoff"
|
||||
- "- Two int fields (one for each player's payoff)"
|
||||
- "Don't forget the semicolon at the end!"
|
||||
next_section_and_step: structures:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: structures:step_1
|
||||
off_topic:
|
||||
next_section_and_step: structures:step_1
|
||||
|
||||
- step_id: step_2
|
||||
title: Payoff Matrix with 2D Array
|
||||
content_blocks:
|
||||
- "## 2D Array for Game Matrix 🎯"
|
||||
- ""
|
||||
- "**Representing a 2x2 game:**"
|
||||
- ""
|
||||
- "**Prisoner's Dilemma has:**"
|
||||
- "- 2 strategies per player: cooperate (0) or defect (1)"
|
||||
- "- 4 possible outcomes: (0,0), (0,1), (1,0), (1,1)"
|
||||
- ""
|
||||
- "**Perfect for a 2D array!**"
|
||||
- ""
|
||||
- "**Array structure:**"
|
||||
- "- First index: player 1's strategy (0 or 1)"
|
||||
- "- Second index: player 2's strategy (0 or 1)"
|
||||
- "- Value: Payoff struct with both payoffs"
|
||||
- ""
|
||||
- "**Conceptual mapping:**"
|
||||
- "```"
|
||||
- "matrix[0][0] = both cooperate"
|
||||
- "matrix[0][1] = p1 cooperates, p2 defects"
|
||||
- "matrix[1][0] = p1 defects, p2 cooperates"
|
||||
- "matrix[1][1] = both defect"
|
||||
- "```"
|
||||
- ""
|
||||
- "**Array declaration concept:**"
|
||||
- "You declare a 2D array of your Payoff struct"
|
||||
- "Then initialize it with the four outcomes"
|
||||
question: "Declare and initialize a 2D array called 'prisoners_dilemma' of Payoff structs representing the Prisoner's Dilemma game. Use indices 0=cooperate, 1=defect. Payoffs: both cooperate (-1,-1), both defect (-2,-2), one defects (0,-3) or (-3,0)."
|
||||
tokens_for_ai: |
|
||||
Looking for 2D array declaration and initialization:
|
||||
|
||||
struct Payoff prisoners_dilemma[2][2] = {
|
||||
{{-1, -1}, {-3, 0}}, // p1 cooperates
|
||||
{{0, -3}, {-2, -2}} // p1 defects
|
||||
};
|
||||
|
||||
Or similar valid initialization.
|
||||
|
||||
Categorize as:
|
||||
- correct: Valid 2D array with proper payoffs
|
||||
- correct_structure: Right format, payoff errors
|
||||
- wrong_dimensions: Not 2x2
|
||||
- syntax_errors: C syntax issues
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect 2D array implementation!
|
||||
- prisoners_dilemma[0][0] = both cooperate = {-1,-1}
|
||||
- prisoners_dilemma[1][1] = both defect = {-2,-2}
|
||||
- prisoners_dilemma[0][1] = p1 cooperate, p2 defect = {-3,0}
|
||||
- prisoners_dilemma[1][0] = p1 defect, p2 cooperate = {0,-3}
|
||||
- Efficient memory layout for game representation!
|
||||
|
||||
If structure right:
|
||||
- Great array structure! Payoff corrections:
|
||||
- Show corrected initialization.
|
||||
- Explain the Prisoner's Dilemma payoffs.
|
||||
|
||||
If wrong dimensions:
|
||||
- Need 2x2 array (2 strategies per player)
|
||||
- struct Payoff name[2][2] = {...};
|
||||
|
||||
If syntax errors:
|
||||
- Show correct C array initialization syntax.
|
||||
- Explain the nested braces structure.
|
||||
buckets: [correct, correct_structure, wrong_dimensions, syntax_errors, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent array implementation!
|
||||
Your 2D array efficiently represents the payoff matrix.
|
||||
Access is simple: prisoners_dilemma[i][j]
|
||||
Memory layout is contiguous and cache-friendly.
|
||||
This is how game theory simulations optimize performance!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: functions:step_1
|
||||
correct_structure:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great structure! Payoff corrections for Prisoner's Dilemma:
|
||||
Show corrected initialization with explanations.
|
||||
Explain why these specific payoffs create the dilemma.
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: functions:step_1
|
||||
wrong_dimensions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Need 2x2 for two-strategy game:
|
||||
|
||||
struct Payoff game[2][2] = {
|
||||
{{-1,-1}, {-3,0}},
|
||||
{{0,-3}, {-2,-2}}
|
||||
};
|
||||
next_section_and_step: structures:step_2
|
||||
syntax_errors:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
C array initialization uses nested braces:
|
||||
|
||||
struct Payoff arr[2][2] = {
|
||||
{row0_col0, row0_col1},
|
||||
{row1_col0, row1_col1}
|
||||
};
|
||||
|
||||
Each Payoff is {p1_payoff, p2_payoff}
|
||||
next_section_and_step: structures:step_2
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Declare: struct Payoff prisoners_dilemma[2][2]"
|
||||
- "Initialize with nested braces: {{...}, {...}}"
|
||||
- "Four outcomes total (2x2 = 4 combinations)"
|
||||
next_section_and_step: structures:step_2
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: structures:step_2
|
||||
off_topic:
|
||||
next_section_and_step: structures:step_2
|
||||
|
||||
- section_id: functions
|
||||
title: Strategy Functions
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Lookup Function
|
||||
content_blocks:
|
||||
- "## Querying the Payoff Matrix 🔍"
|
||||
- ""
|
||||
- "**Create a function to get payoffs**"
|
||||
- ""
|
||||
- "**Function requirements:**"
|
||||
- "- Name: `get_payoff`"
|
||||
- "- Parameters: 2D array (pointer), two strategy indices"
|
||||
- "- Returns: Payoff struct"
|
||||
- ""
|
||||
- "**C function concepts:**"
|
||||
- "- Pass 2D array as pointer"
|
||||
- "- Access with array indexing"
|
||||
- "- Return struct by value"
|
||||
- ""
|
||||
- "**What it does:**"
|
||||
- "Takes strategies (0 or 1 for each player)"
|
||||
- "Returns the corresponding Payoff from the matrix"
|
||||
question: "Write a C function called 'get_payoff' that takes a 2D Payoff array (as pointer) and two integer strategy indices, then returns the Payoff struct for that strategy combination."
|
||||
tokens_for_ai: |
|
||||
Acceptable function signatures:
|
||||
- struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2)
|
||||
- struct Payoff get_payoff(struct Payoff (*matrix)[2], int s1, int s2)
|
||||
|
||||
Function body should:
|
||||
- Return matrix[s1][s2];
|
||||
|
||||
Categorize as:
|
||||
- correct: Valid function with proper syntax
|
||||
- correct_logic: Right idea, minor syntax
|
||||
- wrong_return: Doesn't return Payoff struct
|
||||
- pointer_confusion: Struggles with array parameter
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect function!
|
||||
- Your function cleanly accesses the 2D array.
|
||||
- Returning struct by value is simple and safe here.
|
||||
- Usage: struct Payoff p = get_payoff(game, 0, 1);
|
||||
|
||||
If correct logic:
|
||||
- Great logic! Minor syntax refinement:
|
||||
- Show corrected version.
|
||||
- Explain the C-specific details.
|
||||
|
||||
If wrong return:
|
||||
- Function should return struct Payoff
|
||||
- return matrix[s1][s2]; gives you the Payoff struct.
|
||||
|
||||
If pointer confusion:
|
||||
- For small 2D arrays, can pass as: struct Payoff matrix[2][2]
|
||||
- Or use pointer: struct Payoff (*matrix)[2]
|
||||
- Show working example.
|
||||
buckets: [correct, correct_logic, wrong_return, pointer_confusion, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent function implementation!
|
||||
Your get_payoff function cleanly retrieves outcomes.
|
||||
C's struct return makes this straightforward.
|
||||
You've encapsulated the lookup logic perfectly!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1"}
|
||||
next_section_and_step: simulation:step_1
|
||||
correct_logic:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great logic! Small C syntax refinement:
|
||||
Show polished version.
|
||||
Explain the specific C conventions used.
|
||||
metadata_add: {score: "n+1"}
|
||||
next_section_and_step: simulation:step_1
|
||||
wrong_return:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Return type should be struct Payoff:
|
||||
|
||||
struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) {
|
||||
return matrix[s1][s2];
|
||||
}
|
||||
next_section_and_step: functions:step_1
|
||||
pointer_confusion:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
For 2D array parameter, simple approach:
|
||||
|
||||
struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) {
|
||||
return matrix[s1][s2];
|
||||
}
|
||||
|
||||
C automatically handles the array as pointer.
|
||||
next_section_and_step: functions:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Function signature: struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2)"
|
||||
- "Function body: return matrix[s1][s2];"
|
||||
- "This returns the Payoff at position [s1][s2]"
|
||||
next_section_and_step: functions:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: functions:step_1
|
||||
off_topic:
|
||||
next_section_and_step: functions:step_1
|
||||
|
||||
- section_id: simulation
|
||||
title: Game Simulation
|
||||
steps:
|
||||
- step_id: step_1
|
||||
title: Strategy Enumeration
|
||||
content_blocks:
|
||||
- "## Defining Strategies with Enum 🎲"
|
||||
- ""
|
||||
- "**Making code readable:**"
|
||||
- "Instead of 0 and 1, use named constants!"
|
||||
- ""
|
||||
- "**C enum for strategies:**"
|
||||
- "Enums give names to integer values"
|
||||
- ""
|
||||
- "**What you need:**"
|
||||
- "- Enum name: Strategy (or similar)"
|
||||
- "- Two values: COOPERATE = 0, DEFECT = 1"
|
||||
- ""
|
||||
- "**Why enums improve code:**"
|
||||
- "- get_payoff(game, COOPERATE, DEFECT) is clearer"
|
||||
- "- Better than get_payoff(game, 0, 1)"
|
||||
- "- Self-documenting code"
|
||||
- "- Type safety (to some degree)"
|
||||
question: "Define a C enum called 'Strategy' with two values: COOPERATE (equals 0) and DEFECT (equals 1)."
|
||||
tokens_for_ai: |
|
||||
Looking for enum definition:
|
||||
|
||||
enum Strategy {
|
||||
COOPERATE = 0,
|
||||
DEFECT = 1
|
||||
};
|
||||
|
||||
Or:
|
||||
typedef enum {
|
||||
COOPERATE = 0,
|
||||
DEFECT = 1
|
||||
} Strategy;
|
||||
|
||||
Categorize as:
|
||||
- correct: Valid enum with both values
|
||||
- correct_concept: Right idea, minor syntax
|
||||
- missing_values: Enum but wrong values
|
||||
- no_enum: Doesn't use enum
|
||||
- confused: Wrong approach
|
||||
- set_language: Language preference
|
||||
- off_topic: Unrelated
|
||||
feedback_tokens_for_ai: |
|
||||
If correct:
|
||||
- Perfect enum definition!
|
||||
- Now you can write: enum Strategy s = COOPERATE;
|
||||
- Much more readable than: int s = 0;
|
||||
- Self-documenting code is maintainable code!
|
||||
|
||||
If correct concept:
|
||||
- Great use of enum! Small refinement:
|
||||
- Show corrected version.
|
||||
|
||||
If missing values:
|
||||
- Need both COOPERATE = 0 and DEFECT = 1
|
||||
- Show correct enum.
|
||||
|
||||
If no enum:
|
||||
- C enums create named integer constants:
|
||||
- Show enum syntax.
|
||||
buckets: [correct, correct_concept, missing_values, no_enum, confused, set_language, off_topic]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent enum!
|
||||
Your code is now self-documenting.
|
||||
COOPERATE and DEFECT are much clearer than 0 and 1.
|
||||
This is professional C code style!
|
||||
You've mastered game theory implementation in C!
|
||||
metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"}
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great enum concept! Small polish:
|
||||
Show refined version.
|
||||
You understand C enums well!
|
||||
metadata_add: {score: "n+1", activity_completed: "true"}
|
||||
missing_values:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Need both strategies:
|
||||
|
||||
enum Strategy {
|
||||
COOPERATE = 0,
|
||||
DEFECT = 1
|
||||
};
|
||||
next_section_and_step: simulation:step_1
|
||||
no_enum:
|
||||
content_blocks:
|
||||
- "Define enum with:"
|
||||
- "enum Strategy { COOPERATE = 0, DEFECT = 1 };"
|
||||
- "This creates named constants"
|
||||
next_section_and_step: simulation:step_1
|
||||
confused:
|
||||
content_blocks:
|
||||
- "Enum syntax: enum Name { VALUE1 = 0, VALUE2 = 1 };"
|
||||
- "Creates named integer constants"
|
||||
- "Don't forget the semicolon!"
|
||||
next_section_and_step: simulation:step_1
|
||||
set_language:
|
||||
metadata_add: {language: "the-users-response"}
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: simulation:step_1
|
||||
off_topic:
|
||||
metadata_add: {activity_completed: "true"}
|
||||
|
|
@ -1,663 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are teaching the Monty Hall problem through programming simulation.
|
||||
The user's chosen programming language is stored in metadata.programming_language.
|
||||
ALWAYS provide feedback and code examples in THEIR chosen language.
|
||||
Be encouraging and help them discover the counterintuitive truth through code.
|
||||
|
||||
sections:
|
||||
- section_id: "introduction"
|
||||
title: "Introduction"
|
||||
steps:
|
||||
- step_id: "welcome"
|
||||
title: "Welcome to Monty Hall Simulation"
|
||||
content_blocks:
|
||||
- "# Welcome to the Monty Hall Paradox! 🚪🐐🚗"
|
||||
- ""
|
||||
- "You're about to explore one of the most **counterintuitive** problems in probability."
|
||||
- ""
|
||||
- "We'll use **programming** to prove a mathematical truth that most people find hard to believe!"
|
||||
- ""
|
||||
- "**What you'll learn:**"
|
||||
- "- The famous Monty Hall problem"
|
||||
- "- How to simulate probability with code"
|
||||
- "- Why our intuition fails us"
|
||||
- "- Random number generation, loops, and counters"
|
||||
- ""
|
||||
- "Let's get started! 🎲"
|
||||
|
||||
- step_id: "choose_language"
|
||||
title: "Choose Your Programming Language"
|
||||
question: "What programming language would you like to use? (e.g., Python, JavaScript, C, Java, Go, Rust, etc.)"
|
||||
tokens_for_ai: |
|
||||
The user is choosing their programming language for this activity.
|
||||
|
||||
Categorize as 'valid_language' if they name a real programming language.
|
||||
Examples: Python, JavaScript, C, C++, Java, Go, Rust, Ruby, PHP, Swift, Kotlin, etc.
|
||||
|
||||
Categorize as 'set_language' if they're asking to change the conversation language.
|
||||
|
||||
Categorize as 'need_help' if they seem unsure or ask for recommendations.
|
||||
buckets: [valid_language, set_language, need_help]
|
||||
transitions:
|
||||
valid_language:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Acknowledge their language choice enthusiastically!
|
||||
Tell them it's a great choice for simulation.
|
||||
Store the EXACT language name they said in metadata.programming_language.
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
next_section_and_step: "monty_hall_problem:explain_problem"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Now, what programming language would you like to code in?"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
need_help:
|
||||
content_blocks:
|
||||
- "**Popular choices for beginners:**"
|
||||
- "- **Python** - Easy to read, great for learning"
|
||||
- "- **JavaScript** - Runs in browsers, very accessible"
|
||||
- "- **C** - Classic, teaches fundamentals"
|
||||
- ""
|
||||
- "**For experienced programmers:**"
|
||||
- "- **Java** - Object-oriented, widely used"
|
||||
- "- **Go** - Modern, simple, efficient"
|
||||
- "- **Rust** - Safe, fast, challenging"
|
||||
- ""
|
||||
- "Which would you like to use?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
|
||||
- section_id: "monty_hall_problem"
|
||||
title: "The Monty Hall Problem"
|
||||
steps:
|
||||
- step_id: "explain_problem"
|
||||
title: "The Game Show Scenario"
|
||||
content_blocks:
|
||||
- "# The Monty Hall Problem 🎭"
|
||||
- ""
|
||||
- "Imagine you're on a game show:"
|
||||
- ""
|
||||
- "1. **Three doors** are in front of you: 🚪 🚪 🚪"
|
||||
- "2. Behind **one door** is a **car** 🚗 (the prize!)"
|
||||
- "3. Behind the **other two** are **goats** 🐐🐐 (not prizes)"
|
||||
- ""
|
||||
- "**The Game:**"
|
||||
- "- You pick a door (say Door #1)"
|
||||
- "- The host (Monty Hall) **knows** where the car is"
|
||||
- "- Monty opens one of the OTHER doors, revealing a goat"
|
||||
- "- Monty asks: **\"Do you want to SWITCH to the other unopened door?\"**"
|
||||
- ""
|
||||
- "**The Question:**"
|
||||
- "Should you STAY with your original choice, or SWITCH to the other door?"
|
||||
|
||||
- step_id: "intuition_check"
|
||||
title: "What's Your Intuition?"
|
||||
question: "What do you think? Should you STAY with your original door, SWITCH to the other door, or does it NOT MATTER (50/50 odds)?"
|
||||
tokens_for_ai: |
|
||||
The user is giving their intuitive answer to the Monty Hall problem.
|
||||
|
||||
Categorize as 'stay' if they think staying is better.
|
||||
Categorize as 'switch' if they think switching is better.
|
||||
Categorize as 'same_odds' if they think it doesn't matter (50/50).
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
Categorize as 'unsure' if they don't know or want more explanation.
|
||||
buckets: [stay, switch, same_odds, set_language, unsure]
|
||||
transitions:
|
||||
stay:
|
||||
content_blocks:
|
||||
- "Interesting! That's a common intuition."
|
||||
- ""
|
||||
- "Many people think staying is just as good as switching."
|
||||
- ""
|
||||
- "Let's find out if you're right... through CODE! 🔬"
|
||||
metadata_add:
|
||||
initial_intuition: "stay"
|
||||
next_section_and_step: "probability_prediction:predict_probabilities"
|
||||
switch:
|
||||
content_blocks:
|
||||
- "Aha! You might be onto something! 🤔"
|
||||
- ""
|
||||
- "That's actually the counterintuitive answer that most people reject at first."
|
||||
- ""
|
||||
- "Let's prove it with code! 💻"
|
||||
metadata_add:
|
||||
initial_intuition: "switch"
|
||||
next_section_and_step: "probability_prediction:predict_probabilities"
|
||||
same_odds:
|
||||
content_blocks:
|
||||
- "That's what most people think! It FEELS like 50/50, right?"
|
||||
- ""
|
||||
- "After all, there are two doors left... seems like equal odds."
|
||||
- ""
|
||||
- "But prepare to have your mind blown! 🤯"
|
||||
metadata_add:
|
||||
initial_intuition: "same_odds"
|
||||
next_section_and_step: "probability_prediction:predict_probabilities"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "monty_hall_problem:intuition_check"
|
||||
unsure:
|
||||
content_blocks:
|
||||
- "No problem! This is a VERY tricky problem."
|
||||
- ""
|
||||
- "Even famous mathematicians got it wrong at first!"
|
||||
- ""
|
||||
- "Let's discover the answer together through simulation. 🧪"
|
||||
metadata_add:
|
||||
initial_intuition: "unsure"
|
||||
next_section_and_step: "probability_prediction:predict_probabilities"
|
||||
|
||||
- section_id: "probability_prediction"
|
||||
title: "Probability Prediction"
|
||||
steps:
|
||||
- step_id: "predict_probabilities"
|
||||
title: "Predict the Win Rates"
|
||||
question: |
|
||||
Before we code, make a prediction:
|
||||
|
||||
If you play this game 1000 times...
|
||||
|
||||
- What % of the time will STAYING win?
|
||||
- What % of the time will SWITCHING win?
|
||||
|
||||
Give your prediction (e.g., "50% stay, 50% switch" or "33% stay, 67% switch")
|
||||
tokens_for_ai: |
|
||||
The user is predicting the win rates for stay vs switch strategies.
|
||||
|
||||
The CORRECT answer is: ~33% stay wins, ~67% switch wins (or 1/3 vs 2/3).
|
||||
|
||||
Categorize as 'correct_prediction' if they predict something close to 33/67 or 1/3 vs 2/3.
|
||||
Categorize as 'incorrect_prediction' for any other prediction (like 50/50).
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
Categorize as 'unsure' if they don't want to guess.
|
||||
buckets: [correct_prediction, incorrect_prediction, set_language, unsure]
|
||||
transitions:
|
||||
correct_prediction:
|
||||
content_blocks:
|
||||
- "Wow! You predicted correctly! 🎯"
|
||||
- ""
|
||||
- "**The answer:** Switching wins ~67% of the time (2/3)!"
|
||||
- ""
|
||||
- "Most people find this SHOCKING. Let's prove it with code!"
|
||||
metadata_add:
|
||||
prediction: "the-users-response"
|
||||
predicted_correctly: "true"
|
||||
next_section_and_step: "implement_stay:explain_stay_strategy"
|
||||
incorrect_prediction:
|
||||
content_blocks:
|
||||
- "Good guess! That's what most people predict."
|
||||
- ""
|
||||
- "But here's the truth: **Switching wins ~67% of the time (2/3)!** 🤯"
|
||||
- ""
|
||||
- "I know, I know... it seems impossible."
|
||||
- ""
|
||||
- "That's why we're going to PROVE it with simulation! Let's code it up! 💻"
|
||||
metadata_add:
|
||||
prediction: "the-users-response"
|
||||
predicted_correctly: "false"
|
||||
next_section_and_step: "implement_stay:explain_stay_strategy"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "probability_prediction:predict_probabilities"
|
||||
unsure:
|
||||
content_blocks:
|
||||
- "No worries! The math is tricky."
|
||||
- ""
|
||||
- "Here's the answer: **Switching wins ~67% of the time (2/3)!**"
|
||||
- ""
|
||||
- "Sounds crazy, right? Let's prove it with code! 💻"
|
||||
metadata_add:
|
||||
prediction: "unsure"
|
||||
next_section_and_step: "implement_stay:explain_stay_strategy"
|
||||
|
||||
- section_id: "implement_stay"
|
||||
title: "Implement the Stay Strategy"
|
||||
steps:
|
||||
- step_id: "explain_stay_strategy"
|
||||
title: "Understanding the Stay Strategy"
|
||||
content_blocks:
|
||||
- "# Simulating the STAY Strategy 🎲"
|
||||
- ""
|
||||
- "Let's start by simulating what happens when you ALWAYS stay with your first choice."
|
||||
- ""
|
||||
- "**The Algorithm:**"
|
||||
- "1. Randomly place the car behind one of 3 doors (1, 2, or 3)"
|
||||
- "2. Player randomly picks a door (1, 2, or 3)"
|
||||
- "3. If player's door == car's door, they WIN"
|
||||
- "4. Otherwise, they LOSE"
|
||||
- "5. Repeat this 1000 times"
|
||||
- "6. Calculate: (wins / 1000) × 100 = win percentage"
|
||||
- ""
|
||||
- "**Key Concepts:**"
|
||||
- "- **Random number generation** (pick 1, 2, or 3 randomly)"
|
||||
- "- **Loop** (repeat 1000 times)"
|
||||
- "- **Counter** (track wins)"
|
||||
- "- **Conditional** (if door matches, increment wins)"
|
||||
- ""
|
||||
- "Note: We don't need to simulate Monty opening a door for the STAY strategy, because the player never switches!"
|
||||
|
||||
- step_id: "code_stay_strategy"
|
||||
title: "Code the Stay Strategy"
|
||||
question: |
|
||||
Write a program that simulates the STAY strategy.
|
||||
|
||||
Your program should:
|
||||
- Run 1000 trials
|
||||
- In each trial, randomly pick where the car is (1-3) and where the player picks (1-3)
|
||||
- Count wins when they match
|
||||
- Print the win percentage
|
||||
|
||||
Share your code!
|
||||
tokens_for_ai: |
|
||||
The user is writing code to simulate the STAY strategy in Monty Hall.
|
||||
Their programming language is: metadata.programming_language
|
||||
|
||||
Check if their code demonstrates:
|
||||
1. Random number generation (picking 1-3 for car and player)
|
||||
2. A loop running many trials (doesn't have to be exactly 1000)
|
||||
3. A counter for wins
|
||||
4. Comparison logic (if car_door == player_door, count as win)
|
||||
5. Calculating/printing win percentage
|
||||
|
||||
Categorize as 'correct_code' if they have all 5 elements (even if syntax has minor issues).
|
||||
Categorize as 'partial_code' if they have 3-4 elements or the right idea but incomplete.
|
||||
Categorize as 'needs_help' if they're stuck, have major errors, or ask for help.
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
Categorize as 'off_topic' if completely unrelated.
|
||||
feedback_tokens_for_ai: |
|
||||
The user's programming language is: metadata.programming_language
|
||||
|
||||
If they wrote correct code:
|
||||
- Praise their implementation!
|
||||
- Point out what they did well (random generation, loop structure, etc.)
|
||||
- If they ran it, acknowledge their results (should be ~33%)
|
||||
- Provide a CLEAN, COMPLETE working example in their language showing best practices
|
||||
- Encourage them: "Great! Now let's implement the SWITCH strategy!"
|
||||
|
||||
If they wrote partial code:
|
||||
- Acknowledge what they got right
|
||||
- Gently point out what's missing (e.g., "You have the loop, but how do you pick random doors?")
|
||||
- Give a helpful hint in their specific language
|
||||
- Encourage them to complete it
|
||||
|
||||
If they need help:
|
||||
- Be encouraging!
|
||||
- Provide a complete working example in their language
|
||||
- Explain each part clearly
|
||||
- Ask them to try running it
|
||||
buckets: [correct_code, partial_code, needs_help, set_language, off_topic]
|
||||
transitions:
|
||||
correct_code:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User wrote correct code - see feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
stay_strategy_completed: "true"
|
||||
next_section_and_step: "implement_switch:explain_switch_strategy"
|
||||
partial_code:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User wrote partial code - see feedback_tokens_for_ai above"
|
||||
counts_as_attempt: true
|
||||
next_section_and_step: "implement_stay:code_stay_strategy"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User needs help - see feedback_tokens_for_ai above"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_stay:code_stay_strategy"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_stay:code_stay_strategy"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on implementing the stay strategy simulation."
|
||||
- "Share your code for simulating 1000 trials of staying with your first choice!"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_stay:code_stay_strategy"
|
||||
|
||||
- section_id: "implement_switch"
|
||||
title: "Implement the Switch Strategy"
|
||||
steps:
|
||||
- step_id: "explain_switch_strategy"
|
||||
title: "Understanding the Switch Strategy"
|
||||
content_blocks:
|
||||
- "# Simulating the SWITCH Strategy 🔄"
|
||||
- ""
|
||||
- "Now for the interesting part: simulating what happens when you ALWAYS switch!"
|
||||
- ""
|
||||
- "**The Algorithm:**"
|
||||
- "1. Randomly place the car behind one of 3 doors (1, 2, or 3)"
|
||||
- "2. Player randomly picks a door (1, 2, or 3)"
|
||||
- "3. Monty opens one of the OTHER doors that has a goat"
|
||||
- " - Monty won't open the car door"
|
||||
- " - Monty won't open the player's door"
|
||||
- "4. Player switches to the remaining unopened door"
|
||||
- "5. If the switched door has the car, they WIN"
|
||||
- "6. Repeat 1000 times and calculate win percentage"
|
||||
- ""
|
||||
- "**Key Insight:**"
|
||||
- "When you switch, you win if your FIRST choice was WRONG."
|
||||
- "Since you're wrong 2/3 of the time initially, switching wins 2/3 of the time!"
|
||||
- ""
|
||||
- "**Simplification:**"
|
||||
- "You can actually implement this without simulating Monty's choice!"
|
||||
- "Just check: if player_first_choice != car_door, then switching wins."
|
||||
- "Why? Because if you picked wrong initially, the remaining door MUST have the car!"
|
||||
|
||||
- step_id: "code_switch_strategy"
|
||||
title: "Code the Switch Strategy"
|
||||
question: |
|
||||
Write a program that simulates the SWITCH strategy.
|
||||
|
||||
Your program should:
|
||||
- Run 1000 trials
|
||||
- In each trial, randomly place the car and player's initial choice
|
||||
- Determine if switching would win (switching wins when initial choice was wrong!)
|
||||
- Count wins and print the win percentage
|
||||
|
||||
Share your code!
|
||||
tokens_for_ai: |
|
||||
The user is writing code to simulate the SWITCH strategy in Monty Hall.
|
||||
Their programming language is: metadata.programming_language
|
||||
|
||||
Check if their code demonstrates:
|
||||
1. Random number generation (picking 1-3 for car and initial player choice)
|
||||
2. A loop running many trials
|
||||
3. A counter for wins
|
||||
4. Logic that switching wins when initial choice != car door
|
||||
5. Calculating/printing win percentage
|
||||
|
||||
They might implement it in two ways:
|
||||
- Simple: if first_choice != car_door, then win (because switch gets the car)
|
||||
- Complex: Actually simulate Monty opening a door and switching to remaining door
|
||||
|
||||
Both are correct!
|
||||
|
||||
Categorize as 'correct_code' if they have the right logic.
|
||||
Categorize as 'partial_code' if they have the right idea but incomplete.
|
||||
Categorize as 'needs_help' if they're stuck or have major errors.
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
Categorize as 'off_topic' if completely unrelated.
|
||||
feedback_tokens_for_ai: |
|
||||
The user's programming language is: metadata.programming_language
|
||||
|
||||
If they wrote correct code:
|
||||
- Celebrate! This is the key insight!
|
||||
- Praise their implementation
|
||||
- If they ran it, acknowledge results (should be ~67%)
|
||||
- Provide a clean, complete working example in their language
|
||||
- Point out the beautiful insight: "Switching wins when you're initially wrong (2/3 of the time)!"
|
||||
- Encourage them to compare both strategies
|
||||
|
||||
If they wrote partial code:
|
||||
- Acknowledge what they got right
|
||||
- Hint: "Remember, switching wins when your FIRST choice was WRONG"
|
||||
- Help them complete it
|
||||
|
||||
If they need help:
|
||||
- Be encouraging!
|
||||
- Provide a complete working example
|
||||
- Explain the key insight clearly
|
||||
buckets: [correct_code, partial_code, needs_help, set_language, off_topic]
|
||||
transitions:
|
||||
correct_code:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User wrote correct code - see feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
switch_strategy_completed: "true"
|
||||
next_section_and_step: "run_simulations:compare_results"
|
||||
partial_code:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User wrote partial code - see feedback_tokens_for_ai above"
|
||||
counts_as_attempt: true
|
||||
next_section_and_step: "implement_switch:code_switch_strategy"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User needs help - see feedback_tokens_for_ai above"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_switch:code_switch_strategy"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_switch:code_switch_strategy"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on implementing the switch strategy simulation."
|
||||
- "Share your code for simulating what happens when you always switch!"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implement_switch:code_switch_strategy"
|
||||
|
||||
- section_id: "run_simulations"
|
||||
title: "Run and Compare Simulations"
|
||||
steps:
|
||||
- step_id: "compare_results"
|
||||
title: "Compare the Strategies"
|
||||
question: |
|
||||
Now run BOTH simulations and compare the results!
|
||||
|
||||
Run each simulation with at least 1000 trials (more is better - try 10,000!).
|
||||
|
||||
Report back:
|
||||
- What % does STAY win?
|
||||
- What % does SWITCH win?
|
||||
- What do you observe?
|
||||
tokens_for_ai: |
|
||||
The user is reporting results from running both simulations.
|
||||
|
||||
The expected results are:
|
||||
- STAY wins ~33% (approximately 1/3)
|
||||
- SWITCH wins ~67% (approximately 2/3)
|
||||
|
||||
Categorize as 'correct_results' if they report something close to these percentages.
|
||||
Accept anything in ranges: STAY 30-36%, SWITCH 64-70%
|
||||
|
||||
Categorize as 'incorrect_results' if their numbers are way off (suggesting bugs in code).
|
||||
|
||||
Categorize as 'needs_help' if they couldn't run it or had errors.
|
||||
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
|
||||
Categorize as 'insightful' if they not only report numbers but also express the "aha!" insight.
|
||||
buckets: [correct_results, incorrect_results, insightful, needs_help, set_language]
|
||||
transitions:
|
||||
correct_results:
|
||||
content_blocks:
|
||||
- "**AMAZING!** 🎉"
|
||||
- ""
|
||||
- "You've proven it with code:"
|
||||
- "- STAY wins ~33% (1 out of 3 times)"
|
||||
- "- SWITCH wins ~67% (2 out of 3 times)"
|
||||
- ""
|
||||
- "**Switching DOUBLES your chances of winning!**"
|
||||
- ""
|
||||
- "This is the Monty Hall paradox - counterintuitive but mathematically proven!"
|
||||
metadata_add:
|
||||
simulations_completed: "true"
|
||||
next_section_and_step: "reflection:reflect_on_why"
|
||||
incorrect_results:
|
||||
content_blocks:
|
||||
- "Hmm, those numbers don't look quite right."
|
||||
- ""
|
||||
- "Expected results:"
|
||||
- "- STAY should win ~33%"
|
||||
- "- SWITCH should win ~67%"
|
||||
- ""
|
||||
- "There might be a bug in your code. Want to review the logic?"
|
||||
counts_as_attempt: true
|
||||
next_section_and_step: "run_simulations:compare_results"
|
||||
insightful:
|
||||
content_blocks:
|
||||
- "**YES! You've got it!** 🤯✨"
|
||||
- ""
|
||||
- "You've not only proven it with code, but you UNDERSTAND why!"
|
||||
- ""
|
||||
- "**The key insight:**"
|
||||
- "Switching wins when your first choice was wrong (2/3 of the time)!"
|
||||
- ""
|
||||
- "Beautiful work! 🎊"
|
||||
metadata_add:
|
||||
simulations_completed: "true"
|
||||
deep_understanding: "true"
|
||||
next_section_and_step: "reflection:reflect_on_why"
|
||||
needs_help:
|
||||
content_blocks:
|
||||
- "No problem! Let's troubleshoot."
|
||||
- ""
|
||||
- "Make sure both simulations:"
|
||||
- "1. Run enough trials (1000+)"
|
||||
- "2. Use proper random number generation"
|
||||
- "3. Have correct win conditions"
|
||||
- ""
|
||||
- "Try running them again, or share any errors you're seeing!"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "run_simulations:compare_results"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "run_simulations:compare_results"
|
||||
|
||||
- section_id: "reflection"
|
||||
title: "Reflection and Understanding"
|
||||
steps:
|
||||
- step_id: "reflect_on_why"
|
||||
title: "Why Does Switching Win?"
|
||||
question: |
|
||||
You've seen the proof in code: switching wins ~67% of the time.
|
||||
|
||||
But WHY? Can you explain in your own words why switching is better than staying?
|
||||
|
||||
Think about it and share your explanation!
|
||||
tokens_for_ai: |
|
||||
The user is explaining why switching wins in the Monty Hall problem.
|
||||
|
||||
Good explanations mention:
|
||||
- Initially, you have a 1/3 chance of picking the car (2/3 chance of picking a goat)
|
||||
- Monty ALWAYS reveals a goat from the doors you didn't pick
|
||||
- If you picked a goat initially (2/3 probability), the remaining door MUST have the car
|
||||
- So switching wins whenever you initially picked a goat (2/3 of the time)
|
||||
|
||||
Categorize as 'excellent_explanation' if they demonstrate deep understanding.
|
||||
Categorize as 'good_explanation' if they get the main idea right.
|
||||
Categorize as 'partial_explanation' if they're on the right track but missing key insights.
|
||||
Categorize as 'set_language' if asking to change conversation language.
|
||||
Categorize as 'needs_help' if they're still confused.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide encouraging, detailed feedback on their explanation.
|
||||
|
||||
If excellent/good:
|
||||
- Celebrate their understanding!
|
||||
- Reinforce the key insights they mentioned
|
||||
- Add any nuances they might have missed
|
||||
- Congratulate them on conquering this famous paradox!
|
||||
|
||||
If partial:
|
||||
- Acknowledge what they got right
|
||||
- Gently fill in the missing pieces
|
||||
- Use clear examples
|
||||
|
||||
If needs help:
|
||||
- Be patient and encouraging
|
||||
- Explain step by step:
|
||||
1. You pick a door (1/3 chance of car, 2/3 chance of goat)
|
||||
2. Monty opens a goat door from the OTHER two doors
|
||||
3. If you picked a goat (2/3 probability), the remaining door has the car
|
||||
4. So switching wins 2/3 of the time!
|
||||
buckets: [excellent_explanation, good_explanation, partial_explanation, set_language, needs_help]
|
||||
transitions:
|
||||
excellent_explanation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User has excellent understanding - see feedback_tokens_for_ai"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
understanding_level: "excellent"
|
||||
next_section_and_step: "reflection:conclusion"
|
||||
good_explanation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User has good understanding - see feedback_tokens_for_ai"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
understanding_level: "good"
|
||||
next_section_and_step: "reflection:conclusion"
|
||||
partial_explanation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User has partial understanding - see feedback_tokens_for_ai"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
understanding_level: "partial"
|
||||
next_section_and_step: "reflection:conclusion"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "reflection:reflect_on_why"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "User needs help understanding - see feedback_tokens_for_ai"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
understanding_level: "needs_review"
|
||||
next_section_and_step: "reflection:conclusion"
|
||||
|
||||
- step_id: "conclusion"
|
||||
title: "Congratulations!"
|
||||
content_blocks:
|
||||
- "# 🎊 Congratulations! 🎊"
|
||||
- ""
|
||||
- "You've conquered the **Monty Hall Paradox** through programming!"
|
||||
- ""
|
||||
- "## What You've Learned:"
|
||||
- ""
|
||||
- "✅ **Probability can be counterintuitive** - our gut feelings often fail us"
|
||||
- ""
|
||||
- "✅ **Simulation proves theory** - running 1000s of trials reveals mathematical truth"
|
||||
- ""
|
||||
- "✅ **Programming concepts:**"
|
||||
- " - Random number generation"
|
||||
- " - Loops and iteration"
|
||||
- " - Counters and accumulation"
|
||||
- " - Conditional logic"
|
||||
- ""
|
||||
- "✅ **The Monty Hall insight:** Switching wins 2/3 of the time because you win whenever your initial choice was wrong (which happens 2/3 of the time)!"
|
||||
- ""
|
||||
- "## Fun Facts:"
|
||||
- ""
|
||||
- "- This problem stumped thousands of people, including many mathematicians!"
|
||||
- "- It's named after Monty Hall, host of \"Let's Make a Deal\""
|
||||
- "- Even when shown the math, many people still don't believe it - but your code doesn't lie! 📊"
|
||||
- ""
|
||||
- "## Next Steps:"
|
||||
- ""
|
||||
- "- Try increasing trials to 100,000 or 1,000,000"
|
||||
- "- Visualize the results with graphs"
|
||||
- "- Explore other probability paradoxes"
|
||||
- "- Share this mind-blowing result with friends!"
|
||||
- ""
|
||||
- "**Thank you for exploring this fascinating paradox!** 🚪🐐🚗"
|
||||
- ""
|
||||
- "May your code always compile and your probabilities always surprise you! ✨"
|
||||
|
|
@ -1,645 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_3" # Use code model for programming feedback
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are teaching the multi-armed bandit algorithm to a student.
|
||||
The student has chosen their programming language stored in metadata.programming_language.
|
||||
Always provide feedback in THAT specific language.
|
||||
Be enthusiastic about the gambling/casino metaphor - it makes statistics fun!
|
||||
Encourage exploration of the exploration vs exploitation tradeoff.
|
||||
|
||||
sections:
|
||||
- section_id: "introduction"
|
||||
title: "Welcome to the Casino!"
|
||||
steps:
|
||||
- step_id: "welcome"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "# 🎰 Welcome to Multi-Armed Bandits! 🎰"
|
||||
- ""
|
||||
- "Imagine you're in a casino with multiple slot machines (called 'bandits')."
|
||||
- "Each machine has a different (unknown) payout rate."
|
||||
- ""
|
||||
- "**Your goal:** Maximize your winnings by finding the best machine!"
|
||||
- ""
|
||||
- "**The challenge:** You don't know which machine is best until you try them."
|
||||
- ""
|
||||
- "Should you keep trying all machines equally (exploration)?"
|
||||
- "Or focus on the best one you've found so far (exploitation)?"
|
||||
- ""
|
||||
- "This is the **exploration vs exploitation tradeoff** - one of the most important problems in machine learning!"
|
||||
|
||||
- step_id: "choose_language"
|
||||
title: "Choose Your Programming Language"
|
||||
question: "What programming language would you like to use for this activity? (Python, JavaScript, Java, C++, Go, Rust, or any other language you prefer)"
|
||||
tokens_for_ai: |
|
||||
Extract the programming language from the user's response.
|
||||
Accept any reasonable programming language mention.
|
||||
|
||||
Categorize as 'language_selected' if they mention a programming language.
|
||||
Categorize as 'set_language' if they want to change the conversation language.
|
||||
Categorize as 'unclear' if you can't determine the language.
|
||||
buckets: [language_selected, set_language, unclear]
|
||||
transitions:
|
||||
language_selected:
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Great choice! We'll use that language throughout this activity."
|
||||
- ""
|
||||
- "Let's dive into the problem! 🎰"
|
||||
next_section_and_step: "problem:casino_scenario"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated. Now, which programming language would you like to use for coding?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
unclear:
|
||||
content_blocks:
|
||||
- "I didn't catch which programming language you'd like to use."
|
||||
- "Please specify: Python, JavaScript, Java, C++, Ruby, Go, etc."
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
|
||||
- section_id: "problem"
|
||||
title: "Understanding the Problem"
|
||||
steps:
|
||||
- step_id: "casino_scenario"
|
||||
title: "The Casino Scenario"
|
||||
content_blocks:
|
||||
- "# 🎰 The Multi-Armed Bandit Problem"
|
||||
- ""
|
||||
- "You're in a casino with **3 slot machines**."
|
||||
- ""
|
||||
- "**Machine A:** Unknown win rate (let's say it's actually 30%)"
|
||||
- "**Machine B:** Unknown win rate (let's say it's actually 50%)"
|
||||
- "**Machine C:** Unknown win rate (let's say it's actually 20%)"
|
||||
- ""
|
||||
- "You have **100 coins** to play."
|
||||
- "Each pull costs 1 coin and might win you 1 coin back (net zero) or lose it (net -1)."
|
||||
- ""
|
||||
- "**The catch:** You DON'T know the true win rates!"
|
||||
- "You have to learn them by playing."
|
||||
- ""
|
||||
- "**Real-world applications:**"
|
||||
- "- Website A/B testing (which button converts better?)"
|
||||
- "- Online advertising (which ad gets more clicks?)"
|
||||
- "- Clinical trials (which treatment works better?)"
|
||||
- "- Recommendation systems (which content keeps users engaged?)"
|
||||
|
||||
- step_id: "understand_problem"
|
||||
title: "Understanding Check"
|
||||
question: "In your own words, what is the main challenge of the multi-armed bandit problem?"
|
||||
tokens_for_ai: |
|
||||
The student should understand the exploration vs exploitation tradeoff.
|
||||
|
||||
Categorize as 'excellent' if they mention:
|
||||
- Balancing exploration (trying different options) and exploitation (using the best known option)
|
||||
- Not knowing which option is best initially
|
||||
- Learning while optimizing
|
||||
|
||||
Categorize as 'good' if they mention:
|
||||
- Finding the best option
|
||||
- Learning from limited attempts
|
||||
|
||||
Categorize as 'set_language' if requesting language change.
|
||||
Categorize as 'needs_help' otherwise.
|
||||
buckets: [excellent, good, set_language, needs_help]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Enthusiastically praise their understanding!
|
||||
Highlight the specific insight they showed about exploration vs exploitation.
|
||||
Get them excited about solving this problem.
|
||||
Use emojis! 🎰🎯
|
||||
next_section_and_step: "ab_testing:naive_approach"
|
||||
good:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Praise what they got right.
|
||||
Gently clarify the exploration vs exploitation tradeoff.
|
||||
Encourage them forward.
|
||||
next_section_and_step: "ab_testing:naive_approach"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "problem:understand_problem"
|
||||
needs_help:
|
||||
content_blocks:
|
||||
- "**Hint:** Think about the tradeoff between:"
|
||||
- "- **Exploration:** Trying different machines to learn their rates"
|
||||
- "- **Exploitation:** Using the best machine you've found so far"
|
||||
- ""
|
||||
- "If you only explore, you waste coins on bad machines."
|
||||
- "If you only exploit, you might miss an even better machine!"
|
||||
next_section_and_step: "problem:understand_problem"
|
||||
|
||||
- section_id: "ab_testing"
|
||||
title: "Traditional A/B Testing"
|
||||
steps:
|
||||
- step_id: "naive_approach"
|
||||
title: "The Naive Approach"
|
||||
content_blocks:
|
||||
- "# 📊 Traditional A/B Testing (The Wasteful Way)"
|
||||
- ""
|
||||
- "The traditional approach: **Split traffic evenly!**"
|
||||
- ""
|
||||
- "With 100 coins and 3 machines:"
|
||||
- "- Pull Machine A: 33 times"
|
||||
- "- Pull Machine B: 33 times"
|
||||
- "- Pull Machine C: 34 times"
|
||||
- ""
|
||||
- "Then analyze results and pick the winner."
|
||||
- ""
|
||||
- "**Sounds fair, right?** 🤔"
|
||||
- ""
|
||||
- "**But wait...** What if Machine C is terrible (20% win rate)?"
|
||||
- "You just wasted 34 coins learning what you could have learned after 5 pulls!"
|
||||
- ""
|
||||
- "**The problem with A/B testing:**"
|
||||
- "- Keeps pulling losing arms even after you know they're bad"
|
||||
- "- Wastes resources (users, ad budget, medical treatments)"
|
||||
- "- Takes longer to reach optimal decision"
|
||||
- ""
|
||||
- "Let's implement this to see the waste in action!"
|
||||
|
||||
- step_id: "implement_ab_test"
|
||||
title: "Implement A/B Test Simulation"
|
||||
question: |
|
||||
Write code that simulates a traditional A/B test with 3 slot machines.
|
||||
|
||||
Requirements:
|
||||
- 3 machines with true win rates: [0.3, 0.5, 0.2]
|
||||
- 100 total pulls, split evenly (33, 33, 34)
|
||||
- Track wins and losses for each machine
|
||||
- Calculate and print the estimated win rate for each machine
|
||||
- Calculate total reward (wins - losses)
|
||||
|
||||
Don't worry about perfect code - focus on the logic!
|
||||
tokens_for_ai: |
|
||||
The student is implementing a basic A/B test simulation in their chosen language (metadata.programming_language).
|
||||
|
||||
Check if their code includes:
|
||||
- Arrays/lists to track performance
|
||||
- Random number generation for simulating pulls
|
||||
- Even split of pulls across machines
|
||||
- Calculation of win rates
|
||||
- Total reward tracking
|
||||
|
||||
Categorize as 'excellent' if code is complete and correct.
|
||||
Categorize as 'good_attempt' if logic is mostly right but has minor issues.
|
||||
Categorize as 'needs_guidance' if they're struggling with the structure.
|
||||
Categorize as 'set_language' if requesting language change.
|
||||
Categorize as 'wrong_language' if they used a different programming language than stored in metadata.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their chosen language: {metadata.programming_language}
|
||||
|
||||
If excellent: Praise their implementation! Run through what happens:
|
||||
- Machine A gets pulled 33 times, wins ~10 times (30%)
|
||||
- Machine B gets pulled 33 times, wins ~16 times (50%)
|
||||
- Machine C gets pulled 34 times, wins ~7 times (20%)
|
||||
- Total reward is negative (you lose money overall)
|
||||
- Point out: We kept pulling bad machines even after learning they're bad!
|
||||
|
||||
If good_attempt: Point out what's good, fix specific issues, provide corrected code.
|
||||
|
||||
If needs_guidance: Provide a complete working example with detailed comments.
|
||||
Explain each part: random simulation, tracking, calculating rates.
|
||||
|
||||
If wrong_language: Gently remind them they chose {metadata.programming_language}.
|
||||
Provide the code in the correct language.
|
||||
buckets: [excellent, good_attempt, needs_guidance, set_language, wrong_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for excellent case"
|
||||
metadata_add:
|
||||
ab_test_completed: "true"
|
||||
next_section_and_step: "waste:see_the_waste"
|
||||
good_attempt:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for good_attempt case"
|
||||
metadata_add:
|
||||
ab_test_completed: "true"
|
||||
next_section_and_step: "waste:see_the_waste"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for needs_guidance case"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "ab_testing:implement_ab_test"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "ab_testing:implement_ab_test"
|
||||
wrong_language:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for wrong_language case"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "ab_testing:implement_ab_test"
|
||||
|
||||
- section_id: "waste"
|
||||
title: "Understanding the Waste"
|
||||
steps:
|
||||
- step_id: "see_the_waste"
|
||||
title: "The Waste of A/B Testing"
|
||||
content_blocks:
|
||||
- "# 💸 The Waste of Traditional A/B Testing"
|
||||
- ""
|
||||
- "Let's see what happens in your A/B test simulation:"
|
||||
- ""
|
||||
- "**After 10 pulls of each machine, you might observe:**"
|
||||
- "- Machine A: 3 wins (30% estimated)"
|
||||
- "- Machine B: 5 wins (50% estimated)"
|
||||
- "- Machine C: 2 wins (20% estimated)"
|
||||
- ""
|
||||
- "**You now know Machine B is best!** 🎯"
|
||||
- ""
|
||||
- "**But traditional A/B testing continues:**"
|
||||
- "- Pulls Machine A: 23 more times (waste!)"
|
||||
- "- Pulls Machine B: 23 more times (good!)"
|
||||
- "- Pulls Machine C: 24 more times (waste!)"
|
||||
- ""
|
||||
- "You wasted ~47 pulls on machines you KNEW were inferior!"
|
||||
- ""
|
||||
- "**Cumulative regret:** The total loss from not always choosing the best option."
|
||||
- ""
|
||||
- "In A/B testing: HIGH regret (you keep pulling losing arms)"
|
||||
- "In bandit algorithms: LOW regret (you adapt and focus on winners)"
|
||||
|
||||
- step_id: "understand_regret"
|
||||
title: "Understanding Regret"
|
||||
question: "Why does traditional A/B testing accumulate more regret than an adaptive algorithm?"
|
||||
tokens_for_ai: |
|
||||
Check if student understands that A/B testing:
|
||||
- Continues pulling all arms equally even after learning which is best
|
||||
- Doesn't adapt based on observations
|
||||
- Wastes resources on known-bad options
|
||||
|
||||
Categorize as 'excellent' if they clearly explain the adaptive vs non-adaptive difference.
|
||||
Categorize as 'good' if they understand but less clearly.
|
||||
Categorize as 'set_language' if requesting language change.
|
||||
Categorize as 'needs_clarity' otherwise.
|
||||
buckets: [excellent, good, set_language, needs_clarity]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Celebrate their understanding! 🎉
|
||||
Emphasize: Adaptive algorithms LEARN and SHIFT resources to winners.
|
||||
Get them excited to implement epsilon-greedy!
|
||||
next_section_and_step: "epsilon_greedy:introduce_algorithm"
|
||||
good:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Praise their understanding.
|
||||
Clarify: The key is ADAPTATION - shifting pulls to better arms as you learn.
|
||||
next_section_and_step: "epsilon_greedy:introduce_algorithm"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "waste:understand_regret"
|
||||
needs_clarity:
|
||||
content_blocks:
|
||||
- "**Think about it this way:**"
|
||||
- ""
|
||||
- "**A/B Testing:** Pulls each arm 33 times, no matter what you learn"
|
||||
- "**Adaptive Algorithm:** Pulls good arms MORE as you learn they're good"
|
||||
- ""
|
||||
- "If you learn Machine B is best after 10 pulls, wouldn't you want to pull it MORE than the others?"
|
||||
next_section_and_step: "waste:understand_regret"
|
||||
|
||||
- section_id: "epsilon_greedy"
|
||||
title: "The Epsilon-Greedy Algorithm"
|
||||
steps:
|
||||
- step_id: "introduce_algorithm"
|
||||
title: "Introducing Epsilon-Greedy"
|
||||
content_blocks:
|
||||
- "# 🎯 The Epsilon-Greedy Algorithm"
|
||||
- ""
|
||||
- "Now for the smart approach: **Epsilon-Greedy**"
|
||||
- ""
|
||||
- "**The algorithm:**"
|
||||
- "1. Keep track of each machine's estimated win rate"
|
||||
- "2. With probability **ε** (epsilon): EXPLORE (random machine)"
|
||||
- "3. With probability **1-ε**: EXPLOIT (best machine so far)"
|
||||
- "4. Update estimates after each pull"
|
||||
- ""
|
||||
- "**Example with ε = 0.1 (10% exploration):**"
|
||||
- "- 10% of the time: Try a random machine (exploration)"
|
||||
- "- 90% of the time: Pull the best machine you've found (exploitation)"
|
||||
- ""
|
||||
- "**Why this works:**"
|
||||
- "- Early on: All estimates are uncertain, exploration finds the best"
|
||||
- "- Later on: Estimates are good, exploitation maximizes reward"
|
||||
- "- Always a small chance to explore (in case estimates are wrong)"
|
||||
- ""
|
||||
- "**Key data structures:**"
|
||||
- "- Array of pull counts: [0, 0, 0]"
|
||||
- "- Array of win counts: [0, 0, 0]"
|
||||
- "- Array of win rates: [0.0, 0.0, 0.0]"
|
||||
- ""
|
||||
- "**After each pull:**"
|
||||
- "- Increment pull count for that machine"
|
||||
- "- If win: increment win count"
|
||||
- "- Update win rate = wins / pulls"
|
||||
|
||||
- step_id: "implement_epsilon_greedy"
|
||||
title: "Implement Epsilon-Greedy"
|
||||
question: |
|
||||
Implement the epsilon-greedy algorithm!
|
||||
|
||||
Requirements:
|
||||
- 3 machines with true win rates: [0.3, 0.5, 0.2]
|
||||
- 100 total pulls
|
||||
- Epsilon = 0.1 (10% exploration)
|
||||
- Track: pull counts, win counts, estimated win rates
|
||||
- For each pull:
|
||||
* Random number < 0.1? Explore (random machine)
|
||||
* Otherwise: Exploit (best machine so far)
|
||||
* Simulate the pull (win or lose based on true rate)
|
||||
* Update statistics
|
||||
- Print estimated win rates and total reward
|
||||
|
||||
Focus on the logic - don't worry about perfect code!
|
||||
tokens_for_ai: |
|
||||
The student is implementing epsilon-greedy in their chosen language (metadata.programming_language).
|
||||
|
||||
Check if their code includes:
|
||||
- Arrays/lists for tracking (pull counts, wins, rates)
|
||||
- Random number generation for epsilon decision AND pull simulation
|
||||
- Exploration: pick random machine
|
||||
- Exploitation: pick machine with highest estimated rate (handle ties)
|
||||
- Update logic: increment counts, recalculate rates
|
||||
- Loop for 100 pulls
|
||||
|
||||
Categorize as 'excellent' if implementation is complete and correct.
|
||||
Categorize as 'good_attempt' if logic is mostly right but has issues.
|
||||
Categorize as 'needs_help' if they're struggling with the algorithm.
|
||||
Categorize as 'set_language' if requesting language change.
|
||||
Categorize as 'wrong_language' if using different language than metadata.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their chosen language: {metadata.programming_language}
|
||||
|
||||
If excellent: CELEBRATE! 🎉 This is a real machine learning algorithm!
|
||||
- Explain what should happen: After ~20 pulls, Machine B dominates
|
||||
- Most pulls go to Machine B (the 50% winner)
|
||||
- Occasional exploration keeps checking others
|
||||
- Total reward is MUCH higher than A/B testing
|
||||
- Regret is MUCH lower
|
||||
- Provide their code with enthusiastic comments
|
||||
|
||||
If good_attempt:
|
||||
- Praise what works
|
||||
- Fix specific issues (epsilon logic, argmax, update calculations)
|
||||
- Provide corrected code
|
||||
|
||||
If needs_help:
|
||||
- Provide complete working implementation with detailed comments
|
||||
- Explain the epsilon decision (random < 0.1)
|
||||
- Explain argmax (finding best machine)
|
||||
- Explain update logic (running average)
|
||||
|
||||
If wrong_language: Remind them of their chosen language, provide correct version.
|
||||
buckets: [excellent, good_attempt, needs_help, set_language, wrong_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for excellent case"
|
||||
metadata_add:
|
||||
epsilon_greedy_completed: "true"
|
||||
next_section_and_step: "comparison:compare_algorithms"
|
||||
good_attempt:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for good_attempt case"
|
||||
metadata_add:
|
||||
epsilon_greedy_completed: "true"
|
||||
next_section_and_step: "comparison:compare_algorithms"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for needs_help case"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "epsilon_greedy:implement_epsilon_greedy"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "epsilon_greedy:implement_epsilon_greedy"
|
||||
wrong_language:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Use feedback_tokens_for_ai instructions for wrong_language case"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "epsilon_greedy:implement_epsilon_greedy"
|
||||
|
||||
- section_id: "comparison"
|
||||
title: "A/B vs Bandit Comparison"
|
||||
steps:
|
||||
- step_id: "compare_algorithms"
|
||||
title: "The Dramatic Difference"
|
||||
content_blocks:
|
||||
- "# 📊 A/B Testing vs Epsilon-Greedy: The Results"
|
||||
- ""
|
||||
- "Let's compare what happens with 100 pulls:"
|
||||
- ""
|
||||
- "## 🐌 Traditional A/B Testing:"
|
||||
- "- Machine A (30%): 33 pulls → ~10 wins"
|
||||
- "- Machine B (50%): 33 pulls → ~16 wins"
|
||||
- "- Machine C (20%): 34 pulls → ~7 wins"
|
||||
- "- **Total wins: ~33**"
|
||||
- "- **Total reward: -34** (you lose money!)"
|
||||
- "- **Cumulative regret: ~17** (missed wins from not choosing B)"
|
||||
- ""
|
||||
- "## 🚀 Epsilon-Greedy (ε=0.1):"
|
||||
- "- Machine A (30%): ~5 pulls → ~2 wins"
|
||||
- "- Machine B (50%): ~90 pulls → ~45 wins"
|
||||
- "- Machine C (20%): ~5 pulls → ~1 win"
|
||||
- "- **Total wins: ~48**"
|
||||
- "- **Total reward: -4** (much better!)"
|
||||
- "- **Cumulative regret: ~2** (way lower!)"
|
||||
- ""
|
||||
- "**The difference:**"
|
||||
- "- Epsilon-greedy wins **45% more** (15 extra wins)"
|
||||
- "- Epsilon-greedy saves **30 wasted pulls**"
|
||||
- "- Epsilon-greedy achieves **~88% lower regret**"
|
||||
- ""
|
||||
- "**This is why companies like Google, Facebook, and Amazon use bandit algorithms instead of A/B tests!**"
|
||||
|
||||
- step_id: "tuning_epsilon"
|
||||
title: "Understanding Epsilon"
|
||||
question: "What do you think would happen if we set epsilon to 0.5 (50% exploration) instead of 0.1? Would it be better or worse?"
|
||||
tokens_for_ai: |
|
||||
Check if student understands the exploration/exploitation tradeoff.
|
||||
|
||||
Higher epsilon = more exploration = MORE waste on bad arms.
|
||||
The sweet spot is usually 0.01 to 0.2 depending on uncertainty.
|
||||
|
||||
Categorize as 'correct' if they say worse/more regret/more waste/less focused.
|
||||
Categorize as 'set_language' for language changes.
|
||||
Categorize as 'incorrect' if they think higher epsilon is better.
|
||||
buckets: [correct, set_language, incorrect]
|
||||
transitions:
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Excellent insight! 🎯
|
||||
Explain: Higher epsilon = more random exploration = wasting pulls on known-bad arms.
|
||||
Low epsilon (0.01-0.1) = mostly exploit the best, occasionally explore.
|
||||
Connect to real-world: Early in a campaign, use higher epsilon (more uncertainty).
|
||||
Later, use lower epsilon (you're confident about the best option).
|
||||
Some algorithms even DECREASE epsilon over time!
|
||||
next_section_and_step: "comparison:real_world"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "comparison:tuning_epsilon"
|
||||
incorrect:
|
||||
content_blocks:
|
||||
- "**Think about it:**"
|
||||
- ""
|
||||
- "Epsilon = 0.5 means 50% of pulls are RANDOM."
|
||||
- "Even after you know Machine B is best, half your pulls are wasted on A and C!"
|
||||
- ""
|
||||
- "Lower epsilon = more exploitation of the best option."
|
||||
- "Higher epsilon = more exploration (useful only when very uncertain)."
|
||||
next_section_and_step: "comparison:tuning_epsilon"
|
||||
|
||||
- step_id: "real_world"
|
||||
title: "Real-World Applications"
|
||||
content_blocks:
|
||||
- "# 🌍 Real-World Multi-Armed Bandits"
|
||||
- ""
|
||||
- "Companies use bandit algorithms every day:"
|
||||
- ""
|
||||
- "## 📱 Website Optimization"
|
||||
- "**Problem:** Which button color converts better?"
|
||||
- "**A/B test:** Show red to 50%, blue to 50% for 2 weeks"
|
||||
- "**Bandit:** Start equal, shift traffic to winner within days"
|
||||
- "**Result:** 30-50% more conversions during the test period"
|
||||
- ""
|
||||
- "## 📰 News Headline Testing"
|
||||
- "**Problem:** Which headline gets more clicks?"
|
||||
- "**Bandit:** Show all headlines initially, quickly focus on winners"
|
||||
- "**Result:** Maximize engagement while learning"
|
||||
- ""
|
||||
- "## 💊 Clinical Trials"
|
||||
- "**Problem:** Which treatment works better?"
|
||||
- "**A/B test:** Give treatment A to 50%, treatment B to 50%"
|
||||
- "**Bandit:** Shift MORE patients to effective treatment as you learn"
|
||||
- "**Result:** More lives saved during the trial (ethical win!)"
|
||||
- ""
|
||||
- "## 🎯 Ad Placement"
|
||||
- "**Problem:** Which ad creative performs best?"
|
||||
- "**Bandit:** Automatically shift budget to high-performing ads"
|
||||
- "**Result:** Lower cost per conversion, higher ROI"
|
||||
- ""
|
||||
- "## 🎮 Game Design"
|
||||
- "**Problem:** Which difficulty level keeps players engaged?"
|
||||
- "**Bandit:** Adapt difficulty to maximize playtime"
|
||||
- "**Result:** Better player retention"
|
||||
- ""
|
||||
- "**Advanced algorithms:**"
|
||||
- "- **Thompson Sampling:** Bayesian approach, often better than epsilon-greedy"
|
||||
- "- **UCB (Upper Confidence Bound):** Uses confidence intervals"
|
||||
- "- **Contextual Bandits:** Different arms for different user types"
|
||||
- "- **Bayesian Bandits:** Full probability distributions"
|
||||
|
||||
- section_id: "conclusion"
|
||||
title: "Conclusion"
|
||||
steps:
|
||||
- step_id: "reflection"
|
||||
title: "Final Reflection"
|
||||
question: "In your own words, explain when you would use a bandit algorithm instead of traditional A/B testing, and why."
|
||||
tokens_for_ai: |
|
||||
Student should understand:
|
||||
- Use bandits when you want to minimize regret (wasted resources)
|
||||
- Use bandits when you can't afford to waste on losing options
|
||||
- Use bandits when you want faster optimization
|
||||
- A/B testing is simpler but wastes resources
|
||||
|
||||
Categorize as 'excellent' if they clearly explain the efficiency/regret benefit.
|
||||
Categorize as 'good' if they show understanding but less detailed.
|
||||
Categorize as 'set_language' for language changes.
|
||||
Categorize as 'needs_help' if they don't get the key benefit.
|
||||
buckets: [excellent, good, set_language, needs_help]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Celebrate their mastery! 🎉🎰
|
||||
They now understand a fundamental machine learning algorithm.
|
||||
Highlight specific insights from their answer.
|
||||
Encourage them to implement this in real projects.
|
||||
Mention: This is just the beginning - Thompson Sampling, UCB, contextual bandits are even more powerful!
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "excellent"
|
||||
next_section_and_step: "conclusion:goodbye"
|
||||
good:
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Praise their understanding!
|
||||
Emphasize the key point: Bandits minimize regret by adapting.
|
||||
Encourage them to explore more advanced algorithms.
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "good"
|
||||
next_section_and_step: "conclusion:goodbye"
|
||||
set_language:
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
content_blocks:
|
||||
- "Language preference updated."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
needs_help:
|
||||
content_blocks:
|
||||
- "**Key insight:**"
|
||||
- ""
|
||||
- "Bandit algorithms ADAPT as they learn."
|
||||
- "A/B testing DOESN'T adapt - it keeps wasting resources on losing options."
|
||||
- ""
|
||||
- "**Use bandits when:**"
|
||||
- "- You can't afford to waste resources (money, users, medical treatments)"
|
||||
- "- You want to optimize faster"
|
||||
- "- You want to minimize regret"
|
||||
- ""
|
||||
- "Give it another shot! When would you use a bandit algorithm?"
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
|
||||
- step_id: "goodbye"
|
||||
title: "Congratulations!"
|
||||
content_blocks:
|
||||
- "# 🎰🎉 Congratulations! You've Mastered Multi-Armed Bandits! 🎉🎰"
|
||||
- ""
|
||||
- "You now understand:"
|
||||
- "✅ The exploration vs exploitation tradeoff"
|
||||
- "✅ Why traditional A/B testing is wasteful"
|
||||
- "✅ How epsilon-greedy minimizes regret"
|
||||
- "✅ Real-world applications of bandit algorithms"
|
||||
- "✅ How to implement adaptive learning in code"
|
||||
- ""
|
||||
- "**Next steps:**"
|
||||
- "- Implement Thompson Sampling (Bayesian approach)"
|
||||
- "- Learn UCB (Upper Confidence Bound) algorithm"
|
||||
- "- Explore contextual bandits (different arms for different contexts)"
|
||||
- "- Apply this to a real A/B testing scenario"
|
||||
- ""
|
||||
- "**You're now equipped with a powerful ML algorithm used by Google, Facebook, Amazon, and Netflix!**"
|
||||
- ""
|
||||
- "Keep exploring, keep exploiting! 🚀"
|
||||
|
|
@ -1,361 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Perimeter Security"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Perimeter Security?"
|
||||
content_blocks:
|
||||
- "Welcome to the perimeter security training for a presidential speech."
|
||||
- "Perimeter security involves measures taken to protect the outer boundary of a location to prevent unauthorized access."
|
||||
tokens_for_ai: "Explain what perimeter security is and its importance in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you understand by perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of perimeter security."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of perimeter security. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on perimeter security."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of perimeter security in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of Perimeter Security for a Presidential Speech"
|
||||
content_blocks:
|
||||
- "Perimeter security is crucial for a presidential speech to ensure the safety of the president and attendees."
|
||||
- "It helps prevent unauthorized access, potential threats, and ensures a controlled environment."
|
||||
tokens_for_ai: "Explain the importance of perimeter security for a presidential speech in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is perimeter security important for a presidential speech?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of perimeter security for a presidential speech."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of perimeter security."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of perimeter security in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Planning and Preparation"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Site Assessment"
|
||||
content_blocks:
|
||||
- "The first step in hardening a perimeter is conducting a thorough site assessment."
|
||||
- "Identify potential vulnerabilities, entry points, and areas that need reinforcement."
|
||||
tokens_for_ai: "Explain the importance of site assessment and what it involves in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the purpose of a site assessment in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the purpose of a site assessment."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the site assessment. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the site assessment."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the site assessment in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Security Plan Development"
|
||||
content_blocks:
|
||||
- "Develop a comprehensive security plan based on the site assessment."
|
||||
- "The plan should include security measures, personnel deployment, and emergency response protocols."
|
||||
tokens_for_ai: "Explain how to develop a security plan and what it should include in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What should be included in a security plan for a presidential speech?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know what should be included in a security plan."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the security plan. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the security plan."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the security plan in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Implementing Security Measures"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Physical Barriers"
|
||||
content_blocks:
|
||||
- "Physical barriers such as fences, bollards, and barricades are essential for perimeter security."
|
||||
- "They help control access and prevent unauthorized entry."
|
||||
tokens_for_ai: "Explain the role of physical barriers in perimeter security in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the role of physical barriers in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the role of physical barriers."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of physical barriers. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on physical barriers."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of physical barriers in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Access Control"
|
||||
content_blocks:
|
||||
- "Access control measures include security checkpoints, ID verification, and controlled entry points."
|
||||
- "These measures help ensure that only authorized personnel can enter the secured area."
|
||||
tokens_for_ai: "Explain the importance of access control in perimeter security in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is access control important in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of access control."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of access control. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on access control."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of access control in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Monitoring and Surveillance"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Surveillance Cameras"
|
||||
content_blocks:
|
||||
- "Surveillance cameras are essential for monitoring the perimeter and detecting potential threats."
|
||||
- "They provide real-time video feeds to security personnel."
|
||||
tokens_for_ai: "Explain the role of surveillance cameras in perimeter security in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the role of surveillance cameras in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the role of surveillance cameras."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of surveillance cameras. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on surveillance cameras."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of surveillance cameras in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Security Personnel"
|
||||
content_blocks:
|
||||
- "Security personnel play a crucial role in monitoring the perimeter and responding to incidents."
|
||||
- "They should be strategically positioned and equipped with communication devices."
|
||||
tokens_for_ai: "Explain the role of security personnel in perimeter security in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the role of security personnel in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the role of security personnel."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of security personnel. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on security personnel."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of security personnel in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Emergency Response"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Emergency Protocols"
|
||||
content_blocks:
|
||||
- "Emergency protocols are essential for responding to incidents quickly and effectively."
|
||||
- "They should include evacuation plans, communication procedures, and roles and responsibilities."
|
||||
tokens_for_ai: "Explain the importance of emergency protocols in perimeter security in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why are emergency protocols important in perimeter security?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of emergency protocols."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of emergency protocols. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on emergency protocols."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of emergency protocols in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Communication During Emergencies"
|
||||
content_blocks:
|
||||
- "Effective communication is crucial during emergencies to coordinate response efforts."
|
||||
- "Use radios, phones, and other communication devices to stay in contact with security personnel."
|
||||
tokens_for_ai: "Explain the importance of communication during emergencies in a friendly and engaging manner suitable for a security professional. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is communication important during emergencies?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of communication during emergencies."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of communication during emergencies. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on communication during emergencies."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of communication during emergencies in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The End."
|
||||
content_blocks:
|
||||
- "The End."
|
||||
|
|
@ -1,861 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
You are an enthusiastic evolution scientist teaching genetic algorithms! 🧬
|
||||
|
||||
Use the evolution metaphor throughout - "breeding," "survival of the fittest," "mutations."
|
||||
Be encouraging and celebrate when students grasp concepts.
|
||||
|
||||
The user's programming language is stored in metadata.programming_language (if set).
|
||||
Always provide feedback in their chosen language.
|
||||
|
||||
When evaluating code:
|
||||
- Check if it implements the core concept (not perfect syntax)
|
||||
- Look for understanding of: fitness, selection, crossover, mutation
|
||||
- Praise creative approaches
|
||||
- Guide gently if they're struggling
|
||||
|
||||
sections:
|
||||
- section_id: "introduction"
|
||||
title: "Welcome to Genetic Algorithms"
|
||||
steps:
|
||||
- step_id: "welcome"
|
||||
title: "Welcome"
|
||||
content_blocks:
|
||||
- "# 🧬 Welcome to Genetic Algorithms: Evolution in Code! 🧬"
|
||||
- ""
|
||||
- "Ever wondered how nature solves complex optimization problems?"
|
||||
- ""
|
||||
- "**Nature's secret**: Evolution! 🌱➡️🌳"
|
||||
- ""
|
||||
- "- **Reproduce** the best solutions"
|
||||
- "- **Combine** traits from parents (crossover)"
|
||||
- "- **Mutate** randomly for diversity"
|
||||
- "- **Repeat** for many generations"
|
||||
- ""
|
||||
- "Today, you'll build a genetic algorithm that evolves solutions to problems that would take billions of years to solve by brute force!"
|
||||
- ""
|
||||
- "Let's start by choosing your programming language..."
|
||||
|
||||
- step_id: "choose_language"
|
||||
title: "Choose Programming Language"
|
||||
question: "What programming language would you like to use? (Python, JavaScript, Java, C++, Ruby, Go, Rust, or any language you prefer)"
|
||||
tokens_for_ai: |
|
||||
Extract the programming language from their response.
|
||||
Accept ANY language they mention: Python, JavaScript, Java, C++, C#, Ruby, Go, Rust, PHP, Swift, Kotlin, R, etc.
|
||||
|
||||
Categorize as 'language_chosen' if they name a specific language.
|
||||
Categorize as 'unsure' if they seem uncertain or ask for a recommendation.
|
||||
Categorize as 'off_topic' if completely unrelated.
|
||||
buckets: [language_chosen, unsure, off_topic, set_language]
|
||||
transitions:
|
||||
language_chosen:
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
ai_feedback:
|
||||
tokens_for_ai: |
|
||||
Great choice! Celebrate their language selection.
|
||||
Mention one reason why their language is good for genetic algorithms.
|
||||
(e.g., Python has great list operations, JavaScript has functional programming, etc.)
|
||||
next_section_and_step: "concepts:evolution_metaphor"
|
||||
unsure:
|
||||
content_blocks:
|
||||
- "No worries! 😊"
|
||||
- ""
|
||||
- "**I recommend Python** for beginners - it's clear and readable."
|
||||
- "**JavaScript** is great if you're web-focused."
|
||||
- "**C++** or **Rust** if you want performance."
|
||||
- ""
|
||||
- "Pick whichever you're most comfortable with - genetic algorithms work in ANY language!"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on choosing a programming language first! 🎯"
|
||||
- ""
|
||||
- "Popular choices: Python, JavaScript, Java, C++, Ruby, Go, Rust"
|
||||
- ""
|
||||
- "Which language would you like to use?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "introduction:choose_language"
|
||||
|
||||
- section_id: "concepts"
|
||||
title: "Understanding Genetic Algorithms"
|
||||
steps:
|
||||
- step_id: "evolution_metaphor"
|
||||
title: "The Evolution Metaphor"
|
||||
content_blocks:
|
||||
- "# 🦎 How Evolution Solves Complex Problems 🦎"
|
||||
- ""
|
||||
- "Imagine you want to find the **perfect solution** to a problem."
|
||||
- ""
|
||||
- "**Brute Force**: Try every possibility ❌"
|
||||
- "- Problem: 10 variables, 100 values each = 100^10 = 100 trillion trillion possibilities!"
|
||||
- "- Would take longer than the age of the universe 🌌"
|
||||
- ""
|
||||
- "**Genetic Algorithm**: Let solutions evolve ✅"
|
||||
- "- Start with random guesses (generation 1)"
|
||||
- "- Keep the best ones"
|
||||
- "- Breed them together (crossover)"
|
||||
- "- Add random mutations"
|
||||
- "- Repeat for 100 generations"
|
||||
- "- Find excellent solutions in seconds! ⚡"
|
||||
- ""
|
||||
- "This is how nature designed complex organisms over millions of years."
|
||||
- "We'll do it in code in minutes! 🧬"
|
||||
|
||||
- step_id: "ga_components"
|
||||
title: "Genetic Algorithm Components"
|
||||
content_blocks:
|
||||
- "# 🧬 The 5 Core Components of Genetic Algorithms"
|
||||
- ""
|
||||
- "## 1️⃣ **Population** (Pool of Candidates)"
|
||||
- "- A collection of potential solutions"
|
||||
- "- Each solution is called a **chromosome**"
|
||||
- "- Example: Random strings trying to match \"GENETIC\""
|
||||
- ""
|
||||
- "## 2️⃣ **Fitness Function** (Survival Test)"
|
||||
- "- Measures how good each solution is"
|
||||
- "- Better fitness = more likely to survive"
|
||||
- "- Example: Count matching letters in the string"
|
||||
- ""
|
||||
- "## 3️⃣ **Selection** (Choose the Best)"
|
||||
- "- Pick the fittest individuals to reproduce"
|
||||
- "- Methods: Tournament, Roulette Wheel, Elite Selection"
|
||||
- "- Survival of the fittest! 💪"
|
||||
- ""
|
||||
- "## 4️⃣ **Crossover** (Breeding)"
|
||||
- "- Combine two parent solutions"
|
||||
- "- Create offspring with mixed traits"
|
||||
- "- Example: \"GEN\" + \"TIC\" = \"GENIC\""
|
||||
- ""
|
||||
- "## 5️⃣ **Mutation** (Random Changes)"
|
||||
- "- Randomly modify some offspring"
|
||||
- "- Prevents getting stuck in local optima"
|
||||
- "- Adds diversity to the gene pool 🌈"
|
||||
|
||||
- step_id: "understand_components"
|
||||
title: "Check Understanding"
|
||||
question: "In your own words, why do we need BOTH crossover AND mutation in genetic algorithms? (Hint: Think about what each one does for the solution space)"
|
||||
tokens_for_ai: |
|
||||
Categorize their understanding:
|
||||
|
||||
'deep_understanding' if they mention BOTH:
|
||||
- Crossover combines good traits from parents (exploitation)
|
||||
- Mutation explores new possibilities and prevents premature convergence (exploration)
|
||||
|
||||
'partial_understanding' if they mention ONE of:
|
||||
- Crossover combines solutions
|
||||
- Mutation adds randomness/diversity
|
||||
|
||||
'creative_thinking' if wrong but shows good reasoning about evolution/optimization
|
||||
|
||||
'needs_help' if confused or very brief
|
||||
|
||||
'set_language' if changing language preference
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their chosen language from metadata.programming_language.
|
||||
|
||||
If deep_understanding: Celebrate! Explain this is the exploration-exploitation tradeoff.
|
||||
If partial_understanding: Acknowledge what they got right, add the missing piece.
|
||||
If creative_thinking: Appreciate their reasoning, gently guide to the core concept.
|
||||
If needs_help: Use an analogy - crossover is like breeding dogs (mix best traits), mutation is like genetic mutations (new random traits).
|
||||
buckets: [deep_understanding, partial_understanding, creative_thinking, needs_help, set_language, off_topic]
|
||||
transitions:
|
||||
deep_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Celebrate their understanding! Mention the exploration-exploitation tradeoff is key to many optimization algorithms."
|
||||
next_section_and_step: "problem:define_problem"
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge what they got right. Explain the missing piece (exploration vs exploitation). Be encouraging!"
|
||||
next_section_and_step: "problem:define_problem"
|
||||
creative_thinking:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Appreciate their creative thinking! Guide them to the core: crossover=exploit good solutions, mutation=explore new ones."
|
||||
next_section_and_step: "problem:define_problem"
|
||||
needs_help:
|
||||
content_blocks:
|
||||
- "Let me clarify! 🎯"
|
||||
- ""
|
||||
- "**Crossover** = Combine the BEST traits from parents"
|
||||
- "- Focuses on what's already working"
|
||||
- "- Exploitation of good solutions"
|
||||
- ""
|
||||
- "**Mutation** = Random changes"
|
||||
- "- Explores NEW possibilities"
|
||||
- "- Prevents getting stuck"
|
||||
- ""
|
||||
- "**Together** = Perfect balance of using what works + trying new things! 🧬"
|
||||
next_section_and_step: "problem:define_problem"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "concepts:understand_components"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's stay focused on genetic algorithms! 🧬"
|
||||
- ""
|
||||
- "Think about why we need BOTH crossover (combining solutions) AND mutation (random changes)."
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "concepts:understand_components"
|
||||
|
||||
- section_id: "problem"
|
||||
title: "Define the Problem"
|
||||
steps:
|
||||
- step_id: "define_problem"
|
||||
title: "Our Evolution Challenge"
|
||||
content_blocks:
|
||||
- "# 🎯 The String Evolution Challenge"
|
||||
- ""
|
||||
- "**Goal**: Evolve random characters into the string \"GENETIC\""
|
||||
- ""
|
||||
- "**Starting Point**:"
|
||||
- "- Population of 100 random 7-letter strings"
|
||||
- "- Example: \"XQMZPRL\", \"KDJFHGA\", \"BVNCXZM\""
|
||||
- "- Fitness = 0 (no matching letters)"
|
||||
- ""
|
||||
- "**After 100 Generations**:"
|
||||
- "- Best solution: \"GENETIC\""
|
||||
- "- Fitness = 7 (perfect match!)"
|
||||
- "- We'll watch evolution happen! 🧬➡️✨"
|
||||
- ""
|
||||
- "**Why This Problem?**"
|
||||
- "- Easy to understand fitness (count matching letters)"
|
||||
- "- Brute force: 26^7 = 8 billion possibilities"
|
||||
- "- GA solves it in ~100 generations with population of 100 = 10,000 evaluations"
|
||||
- "- **800,000x faster than brute force!** ⚡"
|
||||
- ""
|
||||
- "Let's build it step by step..."
|
||||
|
||||
- section_id: "implementation"
|
||||
title: "Build the Genetic Algorithm"
|
||||
steps:
|
||||
- step_id: "fitness_function"
|
||||
title: "Step 1: Fitness Function"
|
||||
question: "Write a fitness function that takes a candidate string and returns how many letters match \"GENETIC\" in the correct positions. Think about how you'd measure similarity!"
|
||||
tokens_for_ai: |
|
||||
Evaluate their fitness function code in their chosen language (metadata.programming_language).
|
||||
|
||||
'excellent_implementation' if they:
|
||||
- Compare each character position
|
||||
- Count matches
|
||||
- Handle string comparison correctly
|
||||
- Code looks reasonable (don't nitpick syntax)
|
||||
|
||||
'correct_concept' if they describe the approach correctly even if code has minor issues
|
||||
|
||||
'partial_understanding' if they count total matching letters but not position-specific
|
||||
|
||||
'needs_guidance' if confused or very incomplete
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If excellent_implementation:
|
||||
- Celebrate! Show how this fitness function guides evolution.
|
||||
- Mention: "This is the KEY - fitness drives everything!"
|
||||
|
||||
If correct_concept or partial_understanding:
|
||||
- Acknowledge their understanding
|
||||
- If not position-specific, explain why positions matter
|
||||
- Show a working example of the fitness function
|
||||
|
||||
If needs_guidance:
|
||||
- Provide a complete working example
|
||||
- Explain: loop through each position, count matches
|
||||
- Walk through: "GXXXXXX" vs "GENETIC" = fitness of 1
|
||||
buckets: [excellent_implementation, correct_concept, partial_understanding, needs_guidance, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Celebrate! Show example: fitness('GXXXXXX') = 1, fitness('GENETIC') = 7. Mention this guides ALL evolution!"
|
||||
metadata_add:
|
||||
fitness_complete: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "implementation:selection"
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great concept! Show a polished working version in their language. Explain how it works step-by-step."
|
||||
metadata_add:
|
||||
fitness_complete: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "implementation:selection"
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Good start! Explain why POSITION matters. Show corrected version comparing index-by-index."
|
||||
metadata_add:
|
||||
fitness_complete: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "implementation:selection"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "No worries! Provide complete working fitness function in their language. Walk through example: 'GXXXXXX' scores 1 because only first 'G' matches."
|
||||
metadata_add:
|
||||
fitness_complete: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "implementation:selection"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:fitness_function"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on the fitness function! 🎯"
|
||||
- ""
|
||||
- "Your task: Write code that counts how many letters in a candidate string match \"GENETIC\" at the same positions."
|
||||
- ""
|
||||
- "Example: \"GXXXXXX\" should return 1 (only the G matches)"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:fitness_function"
|
||||
|
||||
- step_id: "selection"
|
||||
title: "Step 2: Selection (Choose the Fittest)"
|
||||
question: "Write a selection function that picks the best individuals from the population. Describe your strategy: will you use tournament selection (pick best from random groups), elite selection (just take the top N), or another method?"
|
||||
tokens_for_ai: |
|
||||
Evaluate their selection implementation/strategy.
|
||||
|
||||
'excellent_implementation' if they:
|
||||
- Describe a valid selection method (tournament, elite, roulette wheel, etc.)
|
||||
- Show code or clear algorithm
|
||||
- Understand it favors higher fitness
|
||||
|
||||
'correct_strategy' if they describe a valid approach even without perfect code
|
||||
|
||||
'creative_approach' if they invent a reasonable selection method
|
||||
|
||||
'needs_guidance' if confused or missing the "favor fitness" concept
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If excellent_implementation:
|
||||
- Praise their approach!
|
||||
- Explain why their method works (survival of fittest)
|
||||
- Show example: population of 100 → select top 50 for breeding
|
||||
|
||||
If correct_strategy or creative_approach:
|
||||
- Validate their thinking
|
||||
- Show a clean implementation
|
||||
- Mention: "Selection pressure drives evolution!"
|
||||
|
||||
If needs_guidance:
|
||||
- Explain selection favors fit individuals
|
||||
- Provide tournament selection example: pick 5 random, take the best, repeat
|
||||
- Or elite selection: sort by fitness, take top 50%
|
||||
buckets: [excellent_implementation, correct_strategy, creative_approach, needs_guidance, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Fantastic! Explain how their selection method creates selection pressure. Show example with fitnesses [7,5,3,1] → likely picks 7 and 5."
|
||||
metadata_add:
|
||||
selection_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:crossover"
|
||||
correct_strategy:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great strategy! Polish their idea with clean code example. Emphasize: this is survival of the fittest in action! 💪"
|
||||
metadata_add:
|
||||
selection_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:crossover"
|
||||
creative_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Love the creativity! Validate if their method favors fitness. Show how it compares to standard approaches."
|
||||
metadata_add:
|
||||
selection_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:crossover"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Let me help! Explain tournament selection: randomly pick 5 individuals, select the fittest, repeat. Show complete code example in their language."
|
||||
metadata_add:
|
||||
selection_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:crossover"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:selection"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on selection! 🎯"
|
||||
- ""
|
||||
- "**Goal**: Pick the best individuals to be parents"
|
||||
- ""
|
||||
- "Think about: How do you favor high-fitness individuals while still allowing some diversity?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:selection"
|
||||
|
||||
- step_id: "crossover"
|
||||
title: "Step 3: Crossover (Breeding)"
|
||||
question: "Write a crossover function that takes two parent strings and creates offspring by combining their genes. How will you mix the parents' traits?"
|
||||
tokens_for_ai: |
|
||||
Evaluate their crossover implementation.
|
||||
|
||||
'excellent_implementation' if they:
|
||||
- Show code that combines two parent strings
|
||||
- Use any valid method (single-point, two-point, uniform)
|
||||
- Create offspring with mixed traits
|
||||
|
||||
'correct_concept' if they describe crossover correctly even with imperfect code
|
||||
|
||||
'creative_approach' if they invent a reasonable mixing strategy
|
||||
|
||||
'needs_guidance' if confused or doesn't mix parent traits
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If excellent_implementation:
|
||||
- Celebrate! Show their crossover in action
|
||||
- Example: parent1="GENXXXX", parent2="XXXETIC" → child="GENETIC" (if lucky!)
|
||||
- Explain: "This is how good traits combine! 🧬"
|
||||
|
||||
If correct_concept or creative_approach:
|
||||
- Validate their approach
|
||||
- Show polished implementation
|
||||
- Demo with example parents
|
||||
|
||||
If needs_guidance:
|
||||
- Explain single-point crossover
|
||||
- Example: "GEN|XXXX" + "XXX|ETIC" → "GENETIC"
|
||||
- Provide complete code in their language
|
||||
buckets: [excellent_implementation, correct_concept, creative_approach, needs_guidance, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Perfect! Show their crossover creating offspring. Example: 'GENXXXX' + 'XXXETIC' → 'GENETIC'. This is evolution magic! ✨"
|
||||
metadata_add:
|
||||
crossover_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:mutation"
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great concept! Show refined code. Demo with concrete parent strings. Emphasize: this exploits existing good genes! 🧬"
|
||||
metadata_add:
|
||||
crossover_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:mutation"
|
||||
creative_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Interesting approach! Validate if it mixes parent traits. Compare to standard single-point crossover."
|
||||
metadata_add:
|
||||
crossover_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:mutation"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Let me show you! Explain single-point crossover with diagram. Provide complete working code in their language."
|
||||
metadata_add:
|
||||
crossover_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "implementation:mutation"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:crossover"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on crossover! 🧬"
|
||||
- ""
|
||||
- "**Goal**: Combine two parent strings to create offspring"
|
||||
- ""
|
||||
- "Think about: How do you mix traits from both parents into a child?"
|
||||
- "One approach: Take first half from parent1, second half from parent2"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:crossover"
|
||||
|
||||
- step_id: "mutation"
|
||||
title: "Step 4: Mutation (Random Changes)"
|
||||
question: "Write a mutation function that randomly changes some characters in a string with small probability (like 1% per character). How will you add this random diversity?"
|
||||
tokens_for_ai: |
|
||||
Evaluate their mutation implementation.
|
||||
|
||||
'excellent_implementation' if they:
|
||||
- Show code that randomly modifies characters
|
||||
- Use low probability (1-10%)
|
||||
- Replace with random letters
|
||||
|
||||
'correct_concept' if they describe mutation correctly even with imperfect code
|
||||
|
||||
'creative_approach' if they use an alternative randomization strategy
|
||||
|
||||
'needs_guidance' if confused or mutates too much/little
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If excellent_implementation:
|
||||
- Praise! Show mutation in action
|
||||
- Example: "GENETIC" → "GENXTIC" (small random change)
|
||||
- Explain: "Prevents getting stuck! Explores new possibilities! 🌈"
|
||||
|
||||
If correct_concept or creative_approach:
|
||||
- Validate their understanding
|
||||
- Show clean implementation with proper probability
|
||||
- Demo: mutate 'GENETIC' a few times
|
||||
|
||||
If needs_guidance:
|
||||
- Explain: loop through characters, 1% chance each mutates to random letter
|
||||
- Show complete code in their language
|
||||
- Warn: too much mutation = random search, too little = stuck
|
||||
buckets: [excellent_implementation, correct_concept, creative_approach, needs_guidance, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Excellent! Demo their mutation. Explain: this is the spark of innovation in evolution! Small random changes = big discoveries. 🌈"
|
||||
metadata_add:
|
||||
mutation_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "execution:main_loop"
|
||||
correct_concept:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great understanding! Show polished code with ~1% mutation rate. Demo mutating 'GENETIC' several times."
|
||||
metadata_add:
|
||||
mutation_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "execution:main_loop"
|
||||
creative_approach:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Creative! Validate their mutation strategy. Compare mutation rate to standard 1-5% per gene."
|
||||
metadata_add:
|
||||
mutation_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "execution:main_loop"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Let me guide you! Explain: for each character, 1% chance to replace with random letter A-Z. Provide complete code in their language."
|
||||
metadata_add:
|
||||
mutation_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "execution:main_loop"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:mutation"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on mutation! 🧬"
|
||||
- ""
|
||||
- "**Goal**: Randomly change some characters to add diversity"
|
||||
- ""
|
||||
- "Think about: For each character, maybe 1% chance to randomly change it to a different letter"
|
||||
- "Why? Prevents getting stuck in local optima!"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "implementation:mutation"
|
||||
|
||||
- section_id: "execution"
|
||||
title: "Run the Evolution!"
|
||||
steps:
|
||||
- step_id: "main_loop"
|
||||
title: "Step 5: The Evolution Loop"
|
||||
question: "Now write the main GA loop that ties everything together: (1) Create random population, (2) For each generation: evaluate fitness, select parents, crossover, mutate, (3) Repeat for 100 generations, (4) Print the best solution. Show me your implementation!"
|
||||
tokens_for_ai: |
|
||||
Evaluate their main GA loop implementation.
|
||||
|
||||
'complete_implementation' if they:
|
||||
- Initialize random population
|
||||
- Have generation loop
|
||||
- Call fitness, selection, crossover, mutation
|
||||
- Track/print best solution
|
||||
|
||||
'correct_structure' if they describe the algorithm correctly even with incomplete code
|
||||
|
||||
'partial_implementation' if missing some components but core loop is there
|
||||
|
||||
'needs_guidance' if confused or very incomplete
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If complete_implementation:
|
||||
- CELEBRATE! They built a complete GA! 🎉
|
||||
- Show example output:
|
||||
"Gen 1: Best='XQMZPRL' (fitness=0)
|
||||
Gen 50: Best='GENXTIX' (fitness=5)
|
||||
Gen 100: Best='GENETIC' (fitness=7) ✨"
|
||||
- Explain: "You just implemented evolution in code!"
|
||||
|
||||
If correct_structure or partial_implementation:
|
||||
- Praise their understanding
|
||||
- Show complete polished version
|
||||
- Explain the flow: random → loop(fitness, select, breed, mutate) → evolved!
|
||||
|
||||
If needs_guidance:
|
||||
- Provide complete working GA code in their language
|
||||
- Walk through: "This is the ENTIRE algorithm in ~50 lines!"
|
||||
- Show sample output across generations
|
||||
buckets: [complete_implementation, correct_structure, partial_implementation, needs_guidance, set_language, off_topic]
|
||||
transitions:
|
||||
complete_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "AMAZING! 🎉 They built a complete genetic algorithm! Show example output with fitness improving over generations. Celebrate: 'You implemented EVOLUTION!' 🧬✨"
|
||||
metadata_add:
|
||||
ga_complete: "true"
|
||||
progress_score: "n+1"
|
||||
implementation_quality: "complete"
|
||||
next_section_and_step: "execution:observe_evolution"
|
||||
correct_structure:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great structure! Show complete polished version with all components. Explain: this is the heart of evolutionary computation! 💚"
|
||||
metadata_add:
|
||||
ga_complete: "true"
|
||||
progress_score: "n+1"
|
||||
implementation_quality: "good"
|
||||
next_section_and_step: "execution:observe_evolution"
|
||||
partial_implementation:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Good start! Fill in missing pieces. Show complete working version. Emphasize: all the parts work together like an ecosystem! 🌱"
|
||||
metadata_add:
|
||||
ga_complete: "true"
|
||||
progress_score: "n+1"
|
||||
implementation_quality: "partial"
|
||||
next_section_and_step: "execution:observe_evolution"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Let me show the complete algorithm! Provide full working GA code in their language (~50 lines). Walk through the flow. Show example output."
|
||||
metadata_add:
|
||||
ga_complete: "true"
|
||||
progress_score: "n+1"
|
||||
implementation_quality: "guided"
|
||||
next_section_and_step: "execution:observe_evolution"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "execution:main_loop"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's focus on the main evolution loop! 🔄"
|
||||
- ""
|
||||
- "You need to:"
|
||||
- "1. Create random population"
|
||||
- "2. Loop for 100 generations:"
|
||||
- " - Calculate fitness for all"
|
||||
- " - Select best individuals"
|
||||
- " - Create offspring via crossover"
|
||||
- " - Mutate offspring"
|
||||
- " - Replace old population"
|
||||
- "3. Print the best solution found"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "execution:main_loop"
|
||||
|
||||
- step_id: "observe_evolution"
|
||||
title: "Observe Evolution in Action"
|
||||
content_blocks:
|
||||
- "# 🔬 Watch Evolution Happen! 🔬"
|
||||
- ""
|
||||
- "If you ran your genetic algorithm, you'd see something AMAZING:"
|
||||
- ""
|
||||
- "```"
|
||||
- "Generation 1: Best='XQMZPRL' Fitness=0 😕"
|
||||
- "Generation 10: Best='GXXXXXX' Fitness=1 🌱"
|
||||
- "Generation 25: Best='GENXXXX' Fitness=3 🌿"
|
||||
- "Generation 50: Best='GENXTIX' Fitness=5 🌳"
|
||||
- "Generation 75: Best='GENETIX' Fitness=6 🌲"
|
||||
- "Generation 100: Best='GENETIC' Fitness=7 ✨🎉"
|
||||
- "```"
|
||||
- ""
|
||||
- "**What just happened?**"
|
||||
- "- Started with pure randomness"
|
||||
- "- Each generation got BETTER"
|
||||
- "- Good genes survived and spread"
|
||||
- "- Mutations found missing letters"
|
||||
- "- **EVOLUTION WORKED!** 🧬"
|
||||
- ""
|
||||
- "**The Math**:"
|
||||
- "- Brute force: 26^7 = 8,031,810,176 tries"
|
||||
- "- GA: 100 generations × 100 population = 10,000 tries"
|
||||
- "- **803,181x faster!** ⚡⚡⚡"
|
||||
- ""
|
||||
- "This is the power of evolutionary algorithms! 💪"
|
||||
|
||||
- step_id: "when_to_use"
|
||||
title: "When to Use Genetic Algorithms"
|
||||
question: "Based on what you learned, when would you use a genetic algorithm versus other optimization methods? Think about problem characteristics that make GAs shine! 🤔"
|
||||
tokens_for_ai: |
|
||||
Evaluate their understanding of when GAs are appropriate.
|
||||
|
||||
'excellent_insight' if they mention 2+ of:
|
||||
- Large search spaces (can't brute force)
|
||||
- No clear gradient/derivative (can't use gradient descent)
|
||||
- Multiple local optima (need exploration)
|
||||
- Complex fitness landscapes
|
||||
- Combinatorial optimization
|
||||
- Don't need perfect solution, just good enough
|
||||
|
||||
'good_understanding' if they mention 1 key insight about search space or optimization landscape
|
||||
|
||||
'partial_understanding' if they understand GAs are for hard problems but vague on details
|
||||
|
||||
'needs_clarification' if confused or missing the key concepts
|
||||
|
||||
'set_language' if changing language
|
||||
|
||||
'off_topic' otherwise
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in their language (metadata.programming_language).
|
||||
|
||||
If excellent_insight:
|
||||
- CELEBRATE their deep understanding! 🎉
|
||||
- Mention real applications: scheduling, circuit design, game AI, neural architecture search
|
||||
- Note: GAs are part of evolutionary computation family
|
||||
|
||||
If good_understanding or partial_understanding:
|
||||
- Validate what they got right
|
||||
- Add missing pieces:
|
||||
* HUGE search spaces (can't enumerate)
|
||||
* Non-differentiable (can't gradient descent)
|
||||
* Multiple peaks (need exploration)
|
||||
- Give examples: TSP, job scheduling, game balancing
|
||||
|
||||
If needs_clarification:
|
||||
- Explain: GAs excel when:
|
||||
* Search space is enormous
|
||||
* No gradient available
|
||||
* Many local optima to escape
|
||||
- Examples: routing problems, game AI, design optimization
|
||||
buckets: [excellent_insight, good_understanding, partial_understanding, needs_clarification, set_language, off_topic]
|
||||
transitions:
|
||||
excellent_insight:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Outstanding! 🌟 List real applications: job scheduling, circuit design, game AI, neural architecture search, traveling salesman. They've mastered when to use GAs!"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "excellent"
|
||||
next_section_and_step: "conclusion:celebrate"
|
||||
good_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Great insight! Add: GAs shine on huge search spaces, non-differentiable problems, multiple local optima. Give examples: TSP, scheduling, game AI."
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "good"
|
||||
next_section_and_step: "conclusion:celebrate"
|
||||
partial_understanding:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "You're on the right track! Explain: GAs work when search space is huge, no gradient, many peaks. Examples: routing, scheduling, design optimization."
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "developing"
|
||||
next_section_and_step: "conclusion:celebrate"
|
||||
needs_clarification:
|
||||
content_blocks:
|
||||
- "Let me clarify when GAs are perfect! 🎯"
|
||||
- ""
|
||||
- "**Use Genetic Algorithms When:**"
|
||||
- ""
|
||||
- "✅ **Huge search space** (billions of possibilities)"
|
||||
- "✅ **No gradient** (can't use calculus-based optimization)"
|
||||
- "✅ **Many local optima** (need to explore, not just climb)"
|
||||
- "✅ **Combinatorial** (scheduling, routing, packing)"
|
||||
- "✅ **Good enough is enough** (don't need perfect solution)"
|
||||
- ""
|
||||
- "**Examples:**"
|
||||
- "- Traveling Salesman Problem 🗺️"
|
||||
- "- Job scheduling 📅"
|
||||
- "- Game AI balancing ⚔️"
|
||||
- "- Circuit design 🔌"
|
||||
- "- Neural architecture search 🧠"
|
||||
- ""
|
||||
- "GAs explore intelligently without needing derivatives or exhaustive search!"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
mastery_level: "developing"
|
||||
next_section_and_step: "conclusion:celebrate"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated! 🌍"
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "execution:when_to_use"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's think about when GAs are the right tool! 🔧"
|
||||
- ""
|
||||
- "Consider: What types of problems would benefit from evolutionary search?"
|
||||
- ""
|
||||
- "Hints:"
|
||||
- "- How big is the search space?"
|
||||
- "- Can you calculate gradients?"
|
||||
- "- Are there many local optima?"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "execution:when_to_use"
|
||||
|
||||
- section_id: "conclusion"
|
||||
title: "Conclusion"
|
||||
steps:
|
||||
- step_id: "celebrate"
|
||||
title: "Congratulations!"
|
||||
content_blocks:
|
||||
- "# 🎉 Congratulations, Evolution Architect! 🎉"
|
||||
- ""
|
||||
- "You just mastered genetic algorithms! Here's what you built:"
|
||||
- ""
|
||||
- "✅ **Fitness Function** - Measured solution quality"
|
||||
- "✅ **Selection** - Survival of the fittest"
|
||||
- "✅ **Crossover** - Breeding the best traits"
|
||||
- "✅ **Mutation** - Exploring new possibilities"
|
||||
- "✅ **Evolution Loop** - Bringing it all together"
|
||||
- ""
|
||||
- "**You learned:**"
|
||||
- "- How nature solves complex optimization problems"
|
||||
- "- Why evolution is an incredible search algorithm"
|
||||
- "- When to use GAs vs other optimization methods"
|
||||
- "- The exploration-exploitation tradeoff"
|
||||
- ""
|
||||
- "**Next Steps:**"
|
||||
- "- Try more complex problems (TSP, knapsack, game AI)"
|
||||
- "- Experiment with different selection/crossover strategies"
|
||||
- "- Learn about: Genetic Programming, Evolution Strategies, Neuroevolution"
|
||||
- "- Apply GAs to real optimization problems in your domain"
|
||||
- ""
|
||||
- "**Remember**: Evolution isn't just biology - it's a powerful computational paradigm! 🧬⚡"
|
||||
- ""
|
||||
- "Keep evolving your code! 🚀"
|
||||
- ""
|
||||
- "— Your Evolution Guide 🦎✨"
|
||||
|
|
@ -1,964 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
classifier_model: "MODEL_1"
|
||||
feedback_model: "MODEL_1"
|
||||
|
||||
tokens_for_ai_rubric: |
|
||||
Evaluate the student's code and understanding based on:
|
||||
- Does their code implement the required functionality?
|
||||
- Is their logic sound, even if syntax has minor issues?
|
||||
- Do they demonstrate understanding of the underlying concepts?
|
||||
- For conceptual questions, do they explain the key ideas correctly?
|
||||
|
||||
Be encouraging! They're building a real game from scratch.
|
||||
Always reference their chosen programming language from metadata.programming_language.
|
||||
|
||||
sections:
|
||||
- section_id: "introduction"
|
||||
title: "Welcome to Connect Four!"
|
||||
steps:
|
||||
- step_id: "welcome"
|
||||
title: "Introduction"
|
||||
content_blocks:
|
||||
- "# 🎮 Build Your Own Connect Four Game!"
|
||||
- ""
|
||||
- "Connect Four is a classic two-player strategy game where players take turns dropping colored discs into a 7-column, 6-row grid."
|
||||
- ""
|
||||
- "**The Goal:** Connect four of your discs in a row - horizontally, vertically, or diagonally - before your opponent does!"
|
||||
- ""
|
||||
- "**What You'll Learn:**"
|
||||
- "- 2D arrays and nested data structures"
|
||||
- "- Game state management"
|
||||
- "- Input validation"
|
||||
- "- Algorithm design (win detection is surprisingly interesting!)"
|
||||
- "- Modular code with functions"
|
||||
- ""
|
||||
- "By the end, you'll have a working Connect Four game you can play!"
|
||||
|
||||
- section_id: "language_choice"
|
||||
title: "Choose Your Programming Language"
|
||||
steps:
|
||||
- step_id: "choose_language"
|
||||
title: "Language Selection"
|
||||
question: "What programming language would you like to use? (Python, JavaScript, Java, C++, C, Ruby, Go, or any other language you prefer)"
|
||||
tokens_for_ai: |
|
||||
The student is selecting their programming language.
|
||||
Store whatever language they choose in metadata.programming_language.
|
||||
Categorize as 'language_selected' if they provide any programming language name.
|
||||
Categorize as 'unclear' if their response is ambiguous or doesn't mention a language.
|
||||
buckets: [language_selected, unclear]
|
||||
transitions:
|
||||
language_selected:
|
||||
content_blocks:
|
||||
- "Excellent choice! All code examples and feedback will be tailored to your language."
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
next_section_and_step: "board_representation:explain_board"
|
||||
unclear:
|
||||
content_blocks:
|
||||
- "I didn't catch which language you'd like to use."
|
||||
- "Please specify a programming language like Python, JavaScript, Java, C++, etc."
|
||||
next_section_and_step: "language_choice:choose_language"
|
||||
|
||||
- section_id: "board_representation"
|
||||
title: "Step 1: Representing the Board"
|
||||
steps:
|
||||
- step_id: "explain_board"
|
||||
title: "Board Data Structure"
|
||||
content_blocks:
|
||||
- "# 📊 Step 1: How Do We Represent the Board?"
|
||||
- ""
|
||||
- "Connect Four uses a 7-column by 6-row grid. We need a data structure to store:"
|
||||
- "- Empty spaces"
|
||||
- "- Player 1's pieces (let's use 'X')"
|
||||
- "- Player 2's pieces (let's use 'O')"
|
||||
- ""
|
||||
- "**The Key Concept: 2D Arrays**"
|
||||
- ""
|
||||
- "A 2D array (or nested list) is like a grid - it has rows and columns. Think of it as a list of lists:"
|
||||
- "- The outer list contains rows"
|
||||
- "- Each inner list contains the columns for that row"
|
||||
- ""
|
||||
- "For Connect Four, we typically use 6 rows (index 0-5) and 7 columns (index 0-6)."
|
||||
- ""
|
||||
- "**Convention:** We'll index from top (row 0) to bottom (row 5), left (column 0) to right (column 6)."
|
||||
|
||||
- step_id: "implement_board"
|
||||
title: "Create the Board"
|
||||
question: "Write code to create an empty Connect Four board (6 rows, 7 columns). Use a 2D array/list and fill it with empty spaces or a placeholder like '.' or ' '."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
The student should create a 2D array/list representing a 6x7 board.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Create a 6x7 2D structure (rows x columns)
|
||||
- Initialize all positions with empty markers
|
||||
- Use appropriate syntax for their language
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Create the right dimensions
|
||||
- Minor syntax issues but concept is clear
|
||||
|
||||
Categorize as 'wrong_dimensions' if they:
|
||||
- Mix up rows/columns (7x6 instead of 6x7)
|
||||
- But otherwise have the right idea
|
||||
|
||||
Categorize as 'needs_guidance' if they:
|
||||
- Don't understand 2D arrays
|
||||
- Need help with the concept
|
||||
|
||||
Categorize as 'set_language' if they want to switch languages.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback based on their code in metadata.programming_language.
|
||||
|
||||
If excellent/correct:
|
||||
- Praise their implementation
|
||||
- Show them their code could be used to initialize: board = create_empty_board()
|
||||
- Mention this is the foundation for everything else
|
||||
|
||||
If wrong_dimensions:
|
||||
- Gently correct: "Close! Remember, 6 ROWS (height) by 7 COLUMNS (width)"
|
||||
- Explain the difference between board[row][col] indexing
|
||||
|
||||
If needs_guidance:
|
||||
- Show a SMALL example of a 2x3 board (not the full solution!)
|
||||
- Explain nested lists/arrays conceptually
|
||||
- Encourage them to try again
|
||||
buckets: [excellent, correct, wrong_dimensions, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
board_created: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "display_board:explain_display"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
board_created: "true"
|
||||
progress_score: "1"
|
||||
next_section_and_step: "display_board:explain_display"
|
||||
wrong_dimensions:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "board_representation:implement_board"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "board_representation:implement_board"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "board_representation:implement_board"
|
||||
|
||||
- section_id: "display_board"
|
||||
title: "Step 2: Displaying the Board"
|
||||
steps:
|
||||
- step_id: "explain_display"
|
||||
title: "Print the Board"
|
||||
content_blocks:
|
||||
- "# 🖨️ Step 2: Displaying the Board"
|
||||
- ""
|
||||
- "Great! You've created the data structure. Now we need to visualize it."
|
||||
- ""
|
||||
- "**The Challenge:** Turn your 2D array into a readable game board on screen."
|
||||
- ""
|
||||
- "**Concept: Nested Loops**"
|
||||
- "- Outer loop: iterate through each row"
|
||||
- "- Inner loop: iterate through each column in that row"
|
||||
- "- Print each cell, then move to the next line after each row"
|
||||
- ""
|
||||
- "**Bonus Points:** Add column numbers (0-6) at the top or bottom to help players choose where to drop!"
|
||||
|
||||
- step_id: "implement_display"
|
||||
title: "Write Display Function"
|
||||
question: "Write a function called display_board (or similar) that takes your board as a parameter and prints it in a readable format. Show each row and make it clear which positions are empty."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
The student should write a function that displays the board.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Use nested loops correctly
|
||||
- Print all rows and columns
|
||||
- Make it readable (spacing, separators, column labels)
|
||||
- Proper function syntax
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Core logic is right (nested loops)
|
||||
- Displays the board even if formatting is basic
|
||||
- Function structure is correct
|
||||
|
||||
Categorize as 'partial' if they:
|
||||
- Have the concept but loops are wrong
|
||||
- Or miss the function wrapper but logic exists
|
||||
|
||||
Categorize as 'needs_help' if they're stuck on nested loops.
|
||||
|
||||
Categorize as 'set_language' if switching languages.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent/correct:
|
||||
- Celebrate: "Your board looks great! 🎨"
|
||||
- Suggest enhancements like separators between cells: | or borders
|
||||
- Note this function will be called after every move
|
||||
|
||||
If partial:
|
||||
- Identify what's working
|
||||
- Guide them on the nested loop structure
|
||||
- Explain outer loop = rows, inner loop = columns
|
||||
|
||||
If needs_help:
|
||||
- Explain nested loop concept clearly
|
||||
- Give pseudocode (not full code):
|
||||
for each row in board:
|
||||
for each cell in row:
|
||||
print cell
|
||||
print newline
|
||||
- Encourage them to try
|
||||
buckets: [excellent, correct, partial, needs_help, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
display_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "drop_piece:explain_drop"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
display_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "drop_piece:explain_drop"
|
||||
partial:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "display_board:implement_display"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "display_board:implement_display"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "display_board:implement_display"
|
||||
|
||||
- section_id: "drop_piece"
|
||||
title: "Step 3: Dropping a Piece"
|
||||
steps:
|
||||
- step_id: "explain_drop"
|
||||
title: "Understanding Gravity"
|
||||
content_blocks:
|
||||
- "# 🪂 Step 3: Dropping a Piece (Gravity!)"
|
||||
- ""
|
||||
- "Now for the fun part: actually playing the game!"
|
||||
- ""
|
||||
- "**The Physics:** When you drop a piece in a column, it falls to the lowest empty space in that column."
|
||||
- ""
|
||||
- "**Algorithm Challenge:**"
|
||||
- "1. Given a column number (0-6)"
|
||||
- "2. Start from the BOTTOM row (row 5)"
|
||||
- "3. Move UP until you find an empty space"
|
||||
- "4. Place the piece there"
|
||||
- ""
|
||||
- "**Think about it:** If column 3 has pieces in rows 5, 4, and 3 (bottom three rows), the next piece drops into row 2."
|
||||
- ""
|
||||
- "**Tip:** You can iterate from the bottom up, or from top down and find the first empty, then check the one below is occupied."
|
||||
|
||||
- step_id: "implement_drop"
|
||||
title: "Write Drop Function"
|
||||
question: "Write a function drop_piece(board, column, player) that drops a player's piece (e.g., 'X' or 'O') into the specified column. It should find the lowest empty row in that column and place the piece there. Return True if successful, False if the column is full."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
The student should implement the drop logic with gravity.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Iterate through rows correctly (bottom-up or top-down)
|
||||
- Find the lowest empty space
|
||||
- Place the piece
|
||||
- Return True/False or similar success indicator
|
||||
- Handle full column edge case
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Core gravity logic works
|
||||
- Minor issues with iteration direction
|
||||
- Concept is clearly understood
|
||||
|
||||
Categorize as 'wrong_direction' if they:
|
||||
- Place pieces at the top instead of letting them fall
|
||||
- But understand they need to find an empty space
|
||||
|
||||
Categorize as 'needs_guidance' if they're struggling with the algorithm.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent/correct:
|
||||
- Celebrate: "Perfect! Gravity works! 🌍"
|
||||
- Explain how this function will be called each turn
|
||||
- Mention: "This is the core game mechanic working!"
|
||||
- Suggest they could add error checking (invalid column numbers)
|
||||
|
||||
If wrong_direction:
|
||||
- Point out pieces should FALL to the bottom
|
||||
- Suggest: "Start checking from row 5 (bottom) and move up"
|
||||
- Or: "Check from row 0 (top) down, but place in the LAST empty row"
|
||||
|
||||
If needs_guidance:
|
||||
- Walk through an example: "Column 2 is empty. Where does the first piece go? Row 5 (bottom)."
|
||||
- "Second piece? Row 4. Third piece? Row 3."
|
||||
- Give pseudocode for the loop structure
|
||||
buckets: [excellent, correct, wrong_direction, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
drop_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "validate_moves:explain_validation"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
drop_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "validate_moves:explain_validation"
|
||||
wrong_direction:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "drop_piece:implement_drop"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "drop_piece:implement_drop"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "drop_piece:implement_drop"
|
||||
|
||||
- section_id: "validate_moves"
|
||||
title: "Step 4: Validating Moves"
|
||||
steps:
|
||||
- step_id: "explain_validation"
|
||||
title: "Input Validation"
|
||||
content_blocks:
|
||||
- "# ✅ Step 4: Validating Moves"
|
||||
- ""
|
||||
- "Before dropping a piece, we need to check if the move is legal!"
|
||||
- ""
|
||||
- "**Invalid Moves:**"
|
||||
- "1. Column number is out of range (< 0 or > 6)"
|
||||
- "2. Column is already full (all 6 rows occupied)"
|
||||
- ""
|
||||
- "**Why This Matters:** Without validation, your game will crash or behave unexpectedly when players make mistakes."
|
||||
- ""
|
||||
- "**Good User Experience:** Tell players WHY their move was invalid and let them try again."
|
||||
|
||||
- step_id: "implement_validation"
|
||||
title: "Write Validation Function"
|
||||
question: "Write a function is_valid_move(board, column) that returns True if the move is valid (column is in range 0-6 and not full), False otherwise. Bonus: Write a function get_player_move() that keeps asking until the player enters a valid column."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Check column range (0-6)
|
||||
- Check if column has any empty space
|
||||
- Return boolean correctly
|
||||
- Bonus: Implement get_player_move with retry loop
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Have validation logic for both conditions
|
||||
- Function structure is correct
|
||||
- Minor syntax issues okay
|
||||
|
||||
Categorize as 'partial' if they:
|
||||
- Only check one condition (range OR fullness)
|
||||
- Concept understood but incomplete
|
||||
|
||||
Categorize as 'needs_help' if struggling with the logic.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent:
|
||||
- Celebrate: "Excellent validation! Your game is robust! 💪"
|
||||
- If they did the bonus: "Love the input loop - great UX!"
|
||||
- Point out how this prevents crashes and improves player experience
|
||||
|
||||
If correct:
|
||||
- Praise: "Great! Your validation works!"
|
||||
- If they didn't do the bonus, mention it would be a nice addition
|
||||
|
||||
If partial:
|
||||
- Identify what they got right
|
||||
- Explain what's missing (range check or fullness check)
|
||||
- Encourage them to add the missing piece
|
||||
|
||||
If needs_help:
|
||||
- Break it down: "Two checks needed:"
|
||||
- "1. Is 0 <= column <= 6?"
|
||||
- "2. Is the top row (row 0) of that column empty?"
|
||||
- Provide pseudocode structure
|
||||
buckets: [excellent, correct, partial, needs_help, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
validation_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "horizontal_win:explain_horizontal"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
validation_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "horizontal_win:explain_horizontal"
|
||||
partial:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "validate_moves:implement_validation"
|
||||
needs_help:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "validate_moves:implement_validation"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "validate_moves:implement_validation"
|
||||
|
||||
- section_id: "horizontal_win"
|
||||
title: "Step 5: Checking Horizontal Wins"
|
||||
steps:
|
||||
- step_id: "explain_horizontal"
|
||||
title: "Win Detection - Horizontal"
|
||||
content_blocks:
|
||||
- "# 🏆 Step 5: Detecting Horizontal Wins"
|
||||
- ""
|
||||
- "Now for the game logic - determining when someone wins!"
|
||||
- ""
|
||||
- "**Horizontal Win:** 4 identical pieces in a row (same row, consecutive columns)"
|
||||
- ""
|
||||
- "**Algorithm Strategy:**"
|
||||
- "1. For each row (0-5)"
|
||||
- "2. For each starting column (0-3) - why only 0-3? Because you need 4 consecutive!"
|
||||
- "3. Check if board[row][col], board[row][col+1], board[row][col+2], board[row][col+3] are all the same player"
|
||||
- ""
|
||||
- "**Key Insight:** You only need to check columns 0-3 as starting positions. If you start at column 4, you can't fit 4 pieces!"
|
||||
|
||||
- step_id: "implement_horizontal"
|
||||
title: "Write Horizontal Check"
|
||||
question: "Write a function check_horizontal_win(board, player) that returns True if the specified player has 4 in a row horizontally, False otherwise. Iterate through all rows and check consecutive columns."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Iterate rows (0-5) correctly
|
||||
- Iterate columns (0-3) as starting positions
|
||||
- Check 4 consecutive positions
|
||||
- Compare against player symbol
|
||||
- Return True when found, False at end
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Logic is sound
|
||||
- Might iterate all columns but still works
|
||||
- Core concept demonstrated
|
||||
|
||||
Categorize as 'wrong_bounds' if they:
|
||||
- Iterate columns 0-6 (causing index errors)
|
||||
- But understand the consecutive checking concept
|
||||
|
||||
Categorize as 'needs_guidance' if struggling with the nested loops or logic.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent:
|
||||
- Celebrate: "Perfect! Horizontal wins are detected! 🎉"
|
||||
- Mention: "Your optimization (only checking columns 0-3) is smart!"
|
||||
- Hint at what's next: "Vertical and diagonal will use similar patterns"
|
||||
|
||||
If correct:
|
||||
- Praise: "Great logic!"
|
||||
- If they checked all columns unnecessarily, gently suggest the optimization
|
||||
- Still move them forward
|
||||
|
||||
If wrong_bounds:
|
||||
- Point out the index error: "Checking column 6 means accessing [row][6+3] which doesn't exist!"
|
||||
- Explain: "If you start at column 4, you check positions 4,5,6,7 - but column 7 doesn't exist"
|
||||
- Suggest: "Only iterate columns 0-3"
|
||||
|
||||
If needs_guidance:
|
||||
- Walk through a concrete example
|
||||
- "Row 2, starting at column 1: check [2][1], [2][2], [2][3], [2][4]"
|
||||
- Provide pseudocode structure
|
||||
buckets: [excellent, correct, wrong_bounds, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
horizontal_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "vertical_win:explain_vertical"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
horizontal_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "vertical_win:explain_vertical"
|
||||
wrong_bounds:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "horizontal_win:implement_horizontal"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "horizontal_win:implement_horizontal"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "horizontal_win:implement_horizontal"
|
||||
|
||||
- section_id: "vertical_win"
|
||||
title: "Step 6: Checking Vertical Wins"
|
||||
steps:
|
||||
- step_id: "explain_vertical"
|
||||
title: "Win Detection - Vertical"
|
||||
content_blocks:
|
||||
- "# 📏 Step 6: Detecting Vertical Wins"
|
||||
- ""
|
||||
- "Similar to horizontal, but now we're checking columns instead of rows!"
|
||||
- ""
|
||||
- "**Vertical Win:** 4 identical pieces stacked vertically (same column, consecutive rows)"
|
||||
- ""
|
||||
- "**Algorithm Strategy:**"
|
||||
- "1. For each column (0-6)"
|
||||
- "2. For each starting row (0-2) - why only 0-2? Same reason as before!"
|
||||
- "3. Check if board[row][col], board[row+1][col], board[row+2][col], board[row+3][col] are all the same player"
|
||||
- ""
|
||||
- "**Pattern Recognition:** Notice how this mirrors the horizontal check, just with rows and columns swapped?"
|
||||
|
||||
- step_id: "implement_vertical"
|
||||
title: "Write Vertical Check"
|
||||
question: "Write a function check_vertical_win(board, player) that returns True if the specified player has 4 in a row vertically. Use the same logic as horizontal, but swap rows and columns."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Iterate columns (0-6) correctly
|
||||
- Iterate rows (0-2) as starting positions
|
||||
- Check 4 consecutive rows in same column
|
||||
- Compare against player symbol
|
||||
- Return boolean correctly
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Logic works
|
||||
- Might iterate all rows but function still works
|
||||
- Understand the pattern
|
||||
|
||||
Categorize as 'wrong_bounds' if they:
|
||||
- Iterate rows 0-5 (causing index errors on row+3)
|
||||
- But the checking logic is right
|
||||
|
||||
Categorize as 'needs_guidance' if struggling.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent:
|
||||
- Celebrate: "Vertical wins detected! 📏 You're seeing the patterns!"
|
||||
- Mention: "Notice how similar this is to horizontal? Same algorithm, different direction!"
|
||||
- Build anticipation: "Diagonal is the trickiest one next!"
|
||||
|
||||
If correct:
|
||||
- Praise: "Great work!"
|
||||
- If they checked all rows, gently suggest the optimization
|
||||
- Acknowledge they're building momentum
|
||||
|
||||
If wrong_bounds:
|
||||
- Explain the index issue with row+3 exceeding bounds
|
||||
- Suggest: "Only start from rows 0-2"
|
||||
|
||||
If needs_guidance:
|
||||
- Remind them of horizontal logic
|
||||
- "It's the same pattern, just checking board[row+i][col] instead of board[row][col+i]"
|
||||
- Provide structure
|
||||
buckets: [excellent, correct, wrong_bounds, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
vertical_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "diagonal_win:explain_diagonal"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
vertical_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "diagonal_win:explain_diagonal"
|
||||
wrong_bounds:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "vertical_win:implement_vertical"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "vertical_win:implement_vertical"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "vertical_win:implement_vertical"
|
||||
|
||||
- section_id: "diagonal_win"
|
||||
title: "Step 7: Checking Diagonal Wins"
|
||||
steps:
|
||||
- step_id: "explain_diagonal"
|
||||
title: "Win Detection - Diagonals"
|
||||
content_blocks:
|
||||
- "# ↗️ Step 7: Detecting Diagonal Wins (The Tricky One!)"
|
||||
- ""
|
||||
- "Diagonals are the most challenging because there are TWO directions to check!"
|
||||
- ""
|
||||
- "**Two Types of Diagonals:**"
|
||||
- "1. **Down-Right (↘️):** row increases, column increases (row+1, col+1)"
|
||||
- "2. **Up-Right (↗️):** row decreases, column increases (row-1, col+1)"
|
||||
- ""
|
||||
- "**Down-Right Diagonal:**"
|
||||
- "- Starting row range: 0-2 (need room to go down 3 rows)"
|
||||
- "- Starting column range: 0-3 (need room to go right 3 columns)"
|
||||
- "- Check: [row][col], [row+1][col+1], [row+2][col+2], [row+3][col+3]"
|
||||
- ""
|
||||
- "**Up-Right Diagonal:**"
|
||||
- "- Starting row range: 3-5 (need room to go up 3 rows)"
|
||||
- "- Starting column range: 0-3 (need room to go right 3 columns)"
|
||||
- "- Check: [row][col], [row-1][col+1], [row-2][col+2], [row-3][col+3]"
|
||||
|
||||
- step_id: "implement_diagonal"
|
||||
title: "Write Diagonal Check"
|
||||
question: "Write a function check_diagonal_win(board, player) that returns True if the player has 4 in a row diagonally (either direction). You need to check both down-right (↘️) and up-right (↗️) diagonals."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
This is the hardest check! Be generous with partial credit.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Check BOTH diagonal directions
|
||||
- Correct row/column bounds for each direction
|
||||
- Proper indexing (row±i, col+i)
|
||||
- Return True when found
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Have both directions
|
||||
- Logic is mostly right
|
||||
- Minor boundary or indexing issues but concept clear
|
||||
|
||||
Categorize as 'one_direction' if they:
|
||||
- Only implement one diagonal direction
|
||||
- But that direction is implemented correctly
|
||||
|
||||
Categorize as 'needs_guidance' if they're struggling with the concept.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent:
|
||||
- Celebrate enthusiastically: "🎉 You conquered diagonals! This is the hardest part!"
|
||||
- Praise: "Both directions working correctly - impressive!"
|
||||
- Mention: "Win detection is now COMPLETE! Your game knows when someone wins!"
|
||||
|
||||
If correct:
|
||||
- Praise: "Great work on the tricky diagonal logic!"
|
||||
- If minor issues, point them out gently
|
||||
- Still acknowledge this is hard and they did well
|
||||
|
||||
If one_direction:
|
||||
- Praise what they did: "Excellent work on [direction] diagonals!"
|
||||
- Explain: "Connect Four needs both directions: ↘️ and ↗️"
|
||||
- Guide them on the second direction's bounds and indexing
|
||||
|
||||
If needs_guidance:
|
||||
- Break down one diagonal type completely
|
||||
- "Down-right example: start at [0][0], check [0][0], [1][1], [2][2], [3][3]"
|
||||
- "Start at [1][2], check [1][2], [2][3], [3][4], [4][5]"
|
||||
- Provide pseudocode structure
|
||||
buckets: [excellent, correct, one_direction, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
diagonal_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "game_loop:explain_loop"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
diagonal_implemented: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "game_loop:explain_loop"
|
||||
one_direction:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "diagonal_win:implement_diagonal"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "diagonal_win:implement_diagonal"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "diagonal_win:implement_diagonal"
|
||||
|
||||
- section_id: "game_loop"
|
||||
title: "Step 8: Building the Game Loop"
|
||||
steps:
|
||||
- step_id: "explain_loop"
|
||||
title: "Putting It All Together"
|
||||
content_blocks:
|
||||
- "# 🔄 Step 8: The Game Loop"
|
||||
- ""
|
||||
- "You have ALL the pieces! Now let's assemble them into a playable game."
|
||||
- ""
|
||||
- "**Game Loop Structure:**"
|
||||
- "1. Initialize the board"
|
||||
- "2. Set current player (start with Player 1)"
|
||||
- "3. **Loop until game ends:**"
|
||||
- " - Display the board"
|
||||
- " - Get current player's move (with validation)"
|
||||
- " - Drop the piece"
|
||||
- " - Check if current player won (all 3 directions)"
|
||||
- " - Check if board is full (tie)"
|
||||
- " - Switch to other player"
|
||||
- "4. Display final board and announce winner"
|
||||
- ""
|
||||
- "**Key Concepts:**"
|
||||
- "- **Game state:** The board changes each turn"
|
||||
- "- **Turn alternation:** Switch between players"
|
||||
- "- **Exit condition:** Win or tie breaks the loop"
|
||||
|
||||
- step_id: "implement_loop"
|
||||
title: "Write Game Loop"
|
||||
question: "Write the main game loop that brings everything together. Initialize the board, alternate between two players, validate moves, drop pieces, check for wins, and announce the winner. You can write this as a play_game() function or as main program logic."
|
||||
tokens_for_ai: |
|
||||
Get the programming language from metadata.programming_language.
|
||||
|
||||
They're writing the FULL game now! Be encouraging.
|
||||
|
||||
Categorize as 'excellent' if they:
|
||||
- Initialize board
|
||||
- Have a game loop (while/for loop until game ends)
|
||||
- Alternate between players
|
||||
- Call display, input, validation, drop, and win check functions
|
||||
- Handle both win and tie conditions
|
||||
- Announce results
|
||||
|
||||
Categorize as 'correct' if they:
|
||||
- Have the main structure
|
||||
- Loop with turn alternation
|
||||
- Call their functions appropriately
|
||||
- Minor logic issues okay if concept is clear
|
||||
|
||||
Categorize as 'partial' if they:
|
||||
- Have some of the structure
|
||||
- Missing key parts (like win checking or player switching)
|
||||
- On the right track but incomplete
|
||||
|
||||
Categorize as 'needs_guidance' if they're struggling to put it together.
|
||||
|
||||
Categorize as 'set_language' for language changes.
|
||||
feedback_tokens_for_ai: |
|
||||
Provide feedback in metadata.programming_language.
|
||||
|
||||
If excellent:
|
||||
- CELEBRATE BIG: "🎉🎮 YOU DID IT! You built a complete Connect Four game!"
|
||||
- List what they've accomplished:
|
||||
* Board representation with 2D arrays
|
||||
* Display with nested loops
|
||||
* Gravity simulation for dropping pieces
|
||||
* Input validation
|
||||
* Win detection in 3 directions
|
||||
* Full game loop with turn management
|
||||
- Suggest enhancements: AI opponent, GUI, undo moves, score tracking
|
||||
- Congratulate them on completing a non-trivial project!
|
||||
|
||||
If correct:
|
||||
- Celebrate: "Your game works! Excellent job! 🎉"
|
||||
- Point out any minor improvements
|
||||
- Still emphasize they built something real and playable
|
||||
|
||||
If partial:
|
||||
- Praise what's working
|
||||
- Identify what's missing
|
||||
- Guide them: "You have X and Y working. Now add Z to complete the loop."
|
||||
- Encourage: "You're so close!"
|
||||
|
||||
If needs_guidance:
|
||||
- Break down the loop structure
|
||||
- "Think of it as: setup -> loop (input, validate, drop, check, switch) -> end"
|
||||
- Provide high-level pseudocode
|
||||
- Encourage them to try integrating one piece at a time
|
||||
buckets: [excellent, correct, partial, needs_guidance, set_language]
|
||||
transitions:
|
||||
excellent:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
game_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
correct:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
game_complete: "true"
|
||||
progress_score: "n+1"
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
partial:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "game_loop:implement_loop"
|
||||
needs_guidance:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
next_section_and_step: "game_loop:implement_loop"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated!"
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "game_loop:implement_loop"
|
||||
|
||||
- section_id: "conclusion"
|
||||
title: "Conclusion & Reflection"
|
||||
steps:
|
||||
- step_id: "reflection"
|
||||
title: "What You've Learned"
|
||||
question: "Reflect on what you learned. What was the most challenging part? What concepts (2D arrays, loops, algorithms, etc.) do you feel more confident about now? What would you add to your game next?"
|
||||
tokens_for_ai: |
|
||||
This is a reflection question. Accept any thoughtful response.
|
||||
|
||||
Categorize as 'thoughtful' if they:
|
||||
- Reflect on specific challenges (likely diagonals!)
|
||||
- Mention concepts they learned
|
||||
- Show understanding of what they built
|
||||
- Maybe mention enhancements
|
||||
|
||||
Categorize as 'brief' if they:
|
||||
- Give a short but genuine response
|
||||
- Show they completed the project
|
||||
|
||||
Categorize as 'off_topic' if they:
|
||||
- Don't engage with the reflection
|
||||
- Are completely off-topic
|
||||
|
||||
Categorize as 'set_language' for language changes (though activity is ending).
|
||||
feedback_tokens_for_ai: |
|
||||
Provide encouraging, celebratory feedback.
|
||||
|
||||
For thoughtful responses:
|
||||
- Acknowledge their specific insights
|
||||
- Validate that diagonals ARE the hardest part
|
||||
- Encourage them to implement their enhancement ideas
|
||||
- Mention how these concepts (2D arrays, nested loops, algorithms) apply to many other programs
|
||||
- Celebrate their achievement of building a complete game from scratch
|
||||
|
||||
For brief responses:
|
||||
- Thank them for their time
|
||||
- Celebrate their completion
|
||||
- Encourage them to keep coding
|
||||
|
||||
For off_topic:
|
||||
- Gently redirect to the question
|
||||
- Ask them to reflect on the experience
|
||||
buckets: [thoughtful, brief, off_topic, set_language]
|
||||
transitions:
|
||||
thoughtful:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: "conclusion:goodbye"
|
||||
brief:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "See feedback_tokens_for_ai above"
|
||||
metadata_add:
|
||||
activity_completed: "true"
|
||||
next_section_and_step: "conclusion:goodbye"
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "Let's take a moment to reflect on what you learned building Connect Four."
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language updated! Though we're at the end of the activity."
|
||||
metadata_add:
|
||||
programming_language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
next_section_and_step: "conclusion:reflection"
|
||||
|
||||
- step_id: "goodbye"
|
||||
title: "Congratulations!"
|
||||
content_blocks:
|
||||
- "# 🎉 Congratulations! You Built Connect Four! 🎮"
|
||||
- ""
|
||||
- "You've successfully created a fully functional Connect Four game from scratch!"
|
||||
- ""
|
||||
- "**What You Accomplished:**"
|
||||
- "✅ Mastered 2D arrays and nested data structures"
|
||||
- "✅ Implemented game physics (gravity!)"
|
||||
- "✅ Wrote input validation"
|
||||
- "✅ Designed win-detection algorithms in 3 directions"
|
||||
- "✅ Built a complete game loop with state management"
|
||||
- "✅ Created something you can actually play!"
|
||||
- ""
|
||||
- "**Next Steps:**"
|
||||
- "- Add an AI opponent (minimax algorithm?)"
|
||||
- "- Create a graphical interface (GUI)"
|
||||
- "- Add animations for falling pieces"
|
||||
- "- Implement undo/redo"
|
||||
- "- Add different board sizes"
|
||||
- ""
|
||||
- "Keep building! Every complex program is just these same concepts combined in creative ways. 🚀"
|
||||
- ""
|
||||
- "Happy coding!"
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Cybersecurity"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Cybersecurity?"
|
||||
content_blocks:
|
||||
- "Welcome to the Cybersecurity Awareness Training."
|
||||
- "Cybersecurity involves protecting computer systems, networks, and data from digital attacks."
|
||||
tokens_for_ai: "Explain what cybersecurity is and its importance in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you understand by cybersecurity?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of cybersecurity."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of cybersecurity. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on cybersecurity."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of cybersecurity in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of Cybersecurity"
|
||||
content_blocks:
|
||||
- "Cybersecurity is crucial to protect sensitive information and maintain privacy."
|
||||
- "It helps prevent data breaches, identity theft, and other cyber threats."
|
||||
tokens_for_ai: "Explain the importance of cybersecurity in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is cybersecurity important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of cybersecurity."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of cybersecurity."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of cybersecurity in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Common Cybersecurity Threats"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Phishing Attacks"
|
||||
content_blocks:
|
||||
- "Phishing attacks involve tricking individuals into providing sensitive information by pretending to be a trustworthy entity."
|
||||
- "These attacks often come in the form of emails or messages that appear legitimate."
|
||||
tokens_for_ai: "Explain what phishing attacks are and how to recognize them in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is a phishing attack and how can you recognize it?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what phishing attacks are and how to recognize them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of phishing attacks. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on phishing attacks."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of phishing attacks in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Malware"
|
||||
content_blocks:
|
||||
- "Malware is malicious software designed to harm or exploit computer systems."
|
||||
- "Common types of malware include viruses, worms, and ransomware."
|
||||
tokens_for_ai: "Explain what malware is and the different types in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is malware and what are some common types?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what malware is and the different types."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of malware. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on malware."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of malware in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Best Practices for Cybersecurity"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Strong Passwords"
|
||||
content_blocks:
|
||||
- "Using strong passwords is one of the simplest and most effective ways to protect your accounts."
|
||||
- "A strong password should be at least 12 characters long and include a mix of letters, numbers, and special characters."
|
||||
tokens_for_ai: "Explain the importance of strong passwords and how to create them in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why are strong passwords important and how can you create one?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of strong passwords and how to create them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of strong passwords. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on strong passwords."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of strong passwords in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Two-Factor Authentication"
|
||||
content_blocks:
|
||||
- "Two-factor authentication (2FA) adds an extra layer of security to your accounts."
|
||||
- "It requires you to provide two forms of identification before accessing your account."
|
||||
tokens_for_ai: "Explain what two-factor authentication is and its benefits in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is two-factor authentication and why is it beneficial?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what two-factor authentication is and its benefits."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of two-factor authentication. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on two-factor authentication."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of two-factor authentication in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Recognizing and Responding to Threats"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Recognizing Phishing Emails"
|
||||
content_blocks:
|
||||
- "Phishing emails often have telltale signs such as poor grammar, urgent language, and suspicious links."
|
||||
- "Always verify the sender's email address and avoid clicking on links or downloading attachments from unknown sources."
|
||||
tokens_for_ai: "Explain how to recognize phishing emails in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How can you recognize a phishing email?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how to recognize phishing emails."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of recognizing phishing emails. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on recognizing phishing emails."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of recognizing phishing emails in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Responding to a Cyber Attack"
|
||||
content_blocks:
|
||||
- "If you suspect a cyber attack, disconnect from the internet and report the incident to your IT department or a cybersecurity professional."
|
||||
- "Do not attempt to fix the issue yourself as it may cause further damage."
|
||||
tokens_for_ai: "Explain how to respond to a suspected cyber attack in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What should you do if you suspect a cyber attack?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to respond to a suspected cyber attack."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of responding to a cyber attack. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on responding to a cyber attack."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of responding to a cyber attack in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The End."
|
||||
content_blocks:
|
||||
- "The End."
|
||||
|
|
@ -1,727 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Financial Literacy"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Financial Literacy?"
|
||||
content_blocks:
|
||||
- "Welcome to the Financial Literacy for Teens course."
|
||||
- "Financial literacy involves understanding how to manage money, including budgeting, saving, investing, and understanding credit."
|
||||
tokens_for_ai: "Explain what financial literacy is and its importance in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you understand by financial literacy?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of financial literacy."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of financial literacy. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on financial literacy."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of financial literacy in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of Financial Literacy"
|
||||
content_blocks:
|
||||
- "Financial literacy is crucial for making informed decisions about money."
|
||||
- "It helps you manage your finances, avoid debt, and plan for the future."
|
||||
tokens_for_ai: "Explain the importance of financial literacy in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is financial literacy important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of financial literacy."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of financial literacy."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of financial literacy in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Budgeting"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is a Budget?"
|
||||
content_blocks:
|
||||
- "A budget is a plan for how you will spend and save your money."
|
||||
- "It helps you track your income and expenses to ensure you are living within your means."
|
||||
tokens_for_ai: "Explain what a budget is and its purpose in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is a budget and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what a budget is and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of a budget. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on what a budget is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of what a budget is in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Creating a Budget"
|
||||
content_blocks:
|
||||
- "To create a budget, start by listing your income and expenses."
|
||||
- "Categorize your expenses into needs (e.g., food, rent) and wants (e.g., entertainment, dining out)."
|
||||
tokens_for_ai: "Explain how to create a budget in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you create a budget?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to create a budget."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of creating a budget. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on creating a budget."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of creating a budget in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Saving Money"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Why Save Money?"
|
||||
content_blocks:
|
||||
- "Saving money is important for achieving financial goals and being prepared for unexpected expenses."
|
||||
- "It helps you build a financial cushion and avoid debt."
|
||||
tokens_for_ai: "Explain the importance of saving money in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is it important to save money?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of saving money."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of saving money. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of saving money."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of saving money in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "How to Save Money"
|
||||
content_blocks:
|
||||
- "To save money, set aside a portion of your income regularly."
|
||||
- "Consider opening a savings account to keep your money safe and earn interest."
|
||||
tokens_for_ai: "Explain how to save money in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How can you save money effectively?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to save money effectively."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of saving money. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on how to save money."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of how to save money in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Investing"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Investing?"
|
||||
content_blocks:
|
||||
- "Investing involves putting your money into assets like stocks, bonds, or real estate to grow your wealth over time."
|
||||
- "It carries some risk, but it can also offer higher returns than saving alone."
|
||||
tokens_for_ai: "Explain what investing is and its purpose in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is investing and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what investing is and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of investing. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on what investing is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of what investing is in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Types of Investments"
|
||||
content_blocks:
|
||||
- "Common types of investments include stocks, bonds, mutual funds, and real estate."
|
||||
- "Each type of investment has its own risk and return profile."
|
||||
tokens_for_ai: "Explain the different types of investments in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What are some common types of investments?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know the different types of investments."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the types of investments. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the types of investments."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the types of investments in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Understanding Credit"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Credit?"
|
||||
content_blocks:
|
||||
- "Credit is the ability to borrow money with the promise to repay it later."
|
||||
- "It allows you to make purchases or access funds that you may not have immediately available."
|
||||
tokens_for_ai: "Explain what credit is and its purpose in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is credit and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what credit is and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of credit. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on what credit is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of what credit is in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Credit Scores"
|
||||
content_blocks:
|
||||
- "A credit score is a numerical representation of your creditworthiness."
|
||||
- "It is based on your credit history and helps lenders determine the risk of lending to you."
|
||||
tokens_for_ai: "Explain what a credit score is and its importance in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is a credit score and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what a credit score is and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of credit scores. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on credit scores."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of credit scores in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "Avoiding Debt"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Debt?"
|
||||
content_blocks:
|
||||
- "Debt is money that you owe to others, typically as a result of borrowing."
|
||||
- "It can come from loans, credit cards, or other forms of borrowing."
|
||||
tokens_for_ai: "Explain what debt is and its implications in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is debt and why is it important to manage it?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what debt is and why it's important to manage it."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of debt. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on what debt is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of what debt is in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Managing Debt"
|
||||
content_blocks:
|
||||
- "To manage debt, make sure to pay your bills on time and avoid taking on more debt than you can handle."
|
||||
- "Create a plan to pay off existing debt and prioritize high-interest debt first."
|
||||
tokens_for_ai: "Explain how to manage debt effectively in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How can you manage debt effectively?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to manage debt effectively."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of managing debt. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on managing debt."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of managing debt in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "Planning for the Future"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Setting Financial Goals"
|
||||
content_blocks:
|
||||
- "Setting financial goals helps you plan for the future and stay motivated to save and invest."
|
||||
- "Your goals can be short-term (e.g., saving for a new phone) or long-term (e.g., saving for college)."
|
||||
tokens_for_ai: "Explain the importance of setting financial goals and how to set them in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is it important to set financial goals and how can you set them?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the importance of setting financial goals and how to set them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of setting financial goals. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on setting financial goals."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of setting financial goals in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Building an Emergency Fund"
|
||||
content_blocks:
|
||||
- "An emergency fund is money set aside to cover unexpected expenses, such as medical bills or car repairs."
|
||||
- "Aim to save at least three to six months' worth of living expenses in your emergency fund."
|
||||
tokens_for_ai: "Explain the importance of an emergency fund and how to build one in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is an emergency fund and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what an emergency fund is and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of an emergency fund. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the emergency fund."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the emergency fund in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_8"
|
||||
title: "Understanding Taxes"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What are Taxes?"
|
||||
content_blocks:
|
||||
- "Taxes are mandatory contributions to government revenue, collected from individuals and businesses."
|
||||
- "They fund public services such as education, healthcare, and infrastructure."
|
||||
tokens_for_ai: "Explain what taxes are and their purpose in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What are taxes and why are they important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what taxes are and why they're important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of taxes. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on taxes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of taxes in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Filing Taxes"
|
||||
content_blocks:
|
||||
- "Filing taxes involves submitting a tax return to report your income and calculate the taxes you owe."
|
||||
- "It's important to file your taxes accurately and on time to avoid penalties."
|
||||
tokens_for_ai: "Explain how to file taxes and the importance of doing so in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you file taxes and why is it important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand how to file taxes and why it's important."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of filing taxes. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on filing taxes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of filing taxes in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_9"
|
||||
title: "Smart Spending"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Needs vs. Wants"
|
||||
content_blocks:
|
||||
- "Understanding the difference between needs and wants is crucial for smart spending."
|
||||
- "Needs are essential for living (e.g., food, shelter), while wants are things you desire but can live without (e.g., new gadgets, dining out)."
|
||||
tokens_for_ai: "Explain the difference between needs and wants in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the difference between needs and wants?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand the difference between needs and wants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of needs and wants. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on needs and wants."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of needs and wants in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Making Smart Purchases"
|
||||
content_blocks:
|
||||
- "To make smart purchases, compare prices, read reviews, and consider the long-term value of the item."
|
||||
- "Avoid impulse buying and stick to your budget."
|
||||
tokens_for_ai: "Explain how to make smart purchases in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How can you make smart purchases?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to make smart purchases."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of making smart purchases. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on making smart purchases."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of making smart purchases in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_10"
|
||||
title: "Protecting Your Finances"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Avoiding Scams"
|
||||
content_blocks:
|
||||
- "Scams are fraudulent schemes designed to steal your money or personal information."
|
||||
- "Be cautious of unsolicited emails, phone calls, or messages asking for your financial information."
|
||||
tokens_for_ai: "Explain how to recognize and avoid scams in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How can you recognize and avoid scams?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how to recognize and avoid scams."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of avoiding scams. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on avoiding scams."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of avoiding scams in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Identity Theft"
|
||||
content_blocks:
|
||||
- "Identity theft occurs when someone steals your personal information to commit fraud."
|
||||
- "Protect your personal information by using strong passwords and being cautious about sharing your details online."
|
||||
tokens_for_ai: "Explain what identity theft is and how to protect against it in a friendly and engaging manner suitable for teens. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is identity theft and how can you protect against it?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand what identity theft is and how to protect against it."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of identity theft. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on identity theft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of identity theft in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
- section_id: "section_11"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Financial Literacy for Teens course!"
|
||||
- "You have learned valuable skills and knowledge that will help you manage your finances effectively."
|
||||
- "Remember, financial literacy is a lifelong journey, and the skills you've gained here will serve you well in the future."
|
||||
- "Keep practicing what you've learned, stay curious, and continue to build your financial knowledge."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
||||
- step_id: "step_3"
|
||||
title: "The End."
|
||||
content_blocks:
|
||||
- "The End."
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Cooking"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Cooking?"
|
||||
content_blocks:
|
||||
- "Welcome to the Basic Cooking Skills course."
|
||||
- "Cooking is the process of preparing food by combining, mixing, and heating ingredients."
|
||||
tokens_for_ai: "Explain what cooking is and its importance in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you understand by cooking?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You have a good understanding of cooking."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of cooking. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on cooking."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of cooking in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Importance of Cooking"
|
||||
content_blocks:
|
||||
- "Cooking is important because it allows you to control what goes into your food."
|
||||
- "It helps you make healthier choices and can be a fun and creative activity."
|
||||
tokens_for_ai: "Explain the importance of cooking in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Why is cooking important?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the importance of cooking."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of the importance. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on the importance of cooking."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of the importance of cooking in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Basic Cooking Techniques"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Chopping and Slicing"
|
||||
content_blocks:
|
||||
- "Chopping and slicing are fundamental cooking techniques."
|
||||
- "Use a sharp knife and a cutting board. Keep your fingers tucked in to avoid cuts."
|
||||
tokens_for_ai: "Explain how to chop and slice ingredients safely in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you chop and slice ingredients safely?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how to chop and slice ingredients safely."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of chopping and slicing. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on chopping and slicing."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of chopping and slicing in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Boiling and Simmering"
|
||||
content_blocks:
|
||||
- "Boiling and simmering are techniques used to cook food in water or broth."
|
||||
- "Boiling involves cooking at a high temperature, while simmering is done at a lower temperature."
|
||||
tokens_for_ai: "Explain the difference between boiling and simmering and how to do them in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is the difference between boiling and simmering, and how do you do them?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the difference between boiling and simmering and how to do them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of boiling and simmering. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on boiling and simmering."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of boiling and simmering in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Simple Recipes"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Scrambled Eggs"
|
||||
content_blocks:
|
||||
- "Scrambled eggs are a simple and nutritious breakfast option."
|
||||
- "Ingredients: 2 eggs, salt, pepper, butter."
|
||||
- "Instructions: Crack the eggs into a bowl, add a pinch of salt and pepper, and whisk. Melt butter in a pan over medium heat, pour in the eggs, and stir until cooked."
|
||||
tokens_for_ai: "Explain how to make scrambled eggs in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you make scrambled eggs?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how to make scrambled eggs."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of making scrambled eggs. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on making scrambled eggs."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of making scrambled eggs in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Pasta with Tomato Sauce"
|
||||
content_blocks:
|
||||
- "Pasta with tomato sauce is a simple and delicious meal."
|
||||
- "Ingredients: 200g pasta, 1 can of tomato sauce, garlic, olive oil, salt, pepper, basil."
|
||||
- "Instructions: Cook the pasta according to the package instructions. In a pan, heat olive oil, add minced garlic, and cook until fragrant. Add tomato sauce, salt, pepper, and basil. Simmer for 10 minutes. Mix with the cooked pasta."
|
||||
tokens_for_ai: "Explain how to make pasta with tomato sauce in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you make pasta with tomato sauce?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to make pasta with tomato sauce."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of making pasta with tomato sauce. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on making pasta with tomato sauce."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of making pasta with tomato sauce in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Baking Basics"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Baking Cookies"
|
||||
content_blocks:
|
||||
- "Baking cookies is a fun and rewarding activity."
|
||||
- "Ingredients: 1 cup butter, 1 cup sugar, 2 cups flour, 1 egg, 1 tsp vanilla extract, 1 tsp baking soda, a pinch of salt."
|
||||
- "Instructions: Preheat the oven to 350°F (175°C). Cream the butter and sugar together. Add the egg and vanilla extract. Mix in the flour, baking soda, and salt. Drop spoonfuls of dough onto a baking sheet and bake for 10-12 minutes."
|
||||
tokens_for_ai: "Explain how to bake cookies in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you bake cookies?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know how to bake cookies."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of baking cookies. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on baking cookies."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of baking cookies in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Baking Bread"
|
||||
content_blocks:
|
||||
- "Baking bread is a rewarding and delicious skill to learn."
|
||||
- "Ingredients: 3 cups flour, 1 packet yeast, 1 cup warm water, 1 tbsp sugar, 1 tsp salt."
|
||||
- "Instructions: Dissolve the yeast and sugar in warm water and let it sit for 5 minutes. Mix in the flour and salt to form a dough. Knead the dough for 10 minutes, then let it rise for 1 hour. Preheat the oven to 375°F (190°C). Shape the dough into a loaf and bake for 25-30 minutes."
|
||||
tokens_for_ai: "Explain how to bake bread in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "How do you bake bread?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know how to bake bread."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of baking bread. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on baking bread."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of baking bread in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Cooking Safety"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Kitchen Safety Tips"
|
||||
content_blocks:
|
||||
- "Safety in the kitchen is crucial to prevent accidents and injuries."
|
||||
- "Always use oven mitts when handling hot items, keep knives sharp and handle them carefully, and clean up spills immediately to avoid slips."
|
||||
tokens_for_ai: "Explain important kitchen safety tips in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What are some important kitchen safety tips?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand important kitchen safety tips."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of kitchen safety tips. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on kitchen safety tips."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of kitchen safety tips in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Food Safety"
|
||||
content_blocks:
|
||||
- "Food safety is essential to prevent foodborne illnesses."
|
||||
- "Always wash your hands before handling food, cook meat to the proper temperature, and store leftovers in the refrigerator promptly."
|
||||
tokens_for_ai: "Explain important food safety practices in a friendly and engaging manner. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What are some important food safety practices?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand important food safety practices."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of food safety practices. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on food safety practices."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of food safety practices in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Basic Cooking Skills course!"
|
||||
- "You have learned valuable skills and techniques that will help you in the kitchen."
|
||||
- "Remember, cooking is a skill that improves with practice, so keep experimenting and trying new recipes."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
||||
|
|
@ -1,652 +0,0 @@
|
|||
default_max_attempts_per_step: 3
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Introduction to Minecraft"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Minecraft?"
|
||||
content_blocks:
|
||||
- "Welcome to the Minecraft Trivia game!"
|
||||
- "Minecraft is a popular sandbox video game where players can build, explore, and survive in a blocky, procedurally-generated 3D world."
|
||||
tokens_for_ai: "Explain what Minecraft is in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What do you know about Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know what Minecraft is."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Minecraft. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Minecraft in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Minecraft Gameplay"
|
||||
content_blocks:
|
||||
- "In Minecraft, players can explore a blocky world, gather resources, craft items, and build structures."
|
||||
- "The game has different modes, including Survival, Creative, Adventure, and Spectator."
|
||||
tokens_for_ai: "Explain the basic gameplay of Minecraft in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe the basic gameplay of Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You understand the basic gameplay of Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Minecraft gameplay. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Minecraft gameplay."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Minecraft gameplay in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Minecraft Mobs"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Friendly Mobs"
|
||||
content_blocks:
|
||||
- "Minecraft has various friendly mobs, such as cows, pigs, and chickens."
|
||||
- "These mobs can be found in different biomes and can be used for resources like food and materials."
|
||||
tokens_for_ai: "Explain what friendly mobs are in Minecraft in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some friendly mobs in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about friendly mobs in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about friendly mobs. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on friendly mobs."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of friendly mobs in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Hostile Mobs"
|
||||
content_blocks:
|
||||
- "Minecraft also has hostile mobs, such as zombies, skeletons, and creepers."
|
||||
- "These mobs attack players and can be found in dark areas or at night."
|
||||
tokens_for_ai: "Explain what hostile mobs are in Minecraft in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some hostile mobs in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about hostile mobs in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about hostile mobs. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on hostile mobs."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of hostile mobs in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_3"
|
||||
title: "Minecraft Biomes"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Overworld Biomes"
|
||||
content_blocks:
|
||||
- "The Overworld in Minecraft has various biomes, such as forests, deserts, and plains."
|
||||
- "Each biome has unique features, resources, and mobs."
|
||||
tokens_for_ai: "Explain what biomes are in Minecraft and describe some Overworld biomes in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some Overworld biomes in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about Overworld biomes in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Overworld biomes. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Overworld biomes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Overworld biomes in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Nether Biomes"
|
||||
content_blocks:
|
||||
- "The Nether is a dangerous dimension in Minecraft with unique biomes, such as Nether Wastes, Crimson Forest, and Warped Forest."
|
||||
- "These biomes have unique resources and hostile mobs."
|
||||
tokens_for_ai: "Explain what Nether biomes are in Minecraft and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some Nether biomes in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about Nether biomes in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Nether biomes. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Nether biomes."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Nether biomes in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_4"
|
||||
title: "Minecraft Items and Blocks"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Common Blocks"
|
||||
content_blocks:
|
||||
- "Minecraft has many common blocks, such as dirt, stone, and wood."
|
||||
- "These blocks are used for building and crafting."
|
||||
tokens_for_ai: "Explain what common blocks are in Minecraft and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some common blocks in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about common blocks in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about common blocks. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on common blocks."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of common blocks in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Crafting Items"
|
||||
content_blocks:
|
||||
- "Crafting is an essential part of Minecraft, allowing players to create items like tools, weapons, and armor."
|
||||
- "Common crafting items include sticks, planks, and ingots."
|
||||
tokens_for_ai: "Explain what crafting items are in Minecraft and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some crafting items in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about crafting items in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about crafting items. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on crafting items."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of crafting items in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_5"
|
||||
title: "Minecraft Structures"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Villages"
|
||||
content_blocks:
|
||||
- "Villages are structures in Minecraft where villagers live and work."
|
||||
- "They have houses, farms, and other buildings."
|
||||
tokens_for_ai: "Explain what villages are in Minecraft and describe their features in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe what a village is in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know what a village is in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about villages. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on villages."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of villages in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Strongholds"
|
||||
content_blocks:
|
||||
- "Strongholds are underground structures in Minecraft that contain the End Portal."
|
||||
- "They are made of stone bricks and have various rooms and corridors."
|
||||
tokens_for_ai: "Explain what strongholds are in Minecraft and describe their features in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe what a stronghold is in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know what a stronghold is in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about strongholds. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on strongholds."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of strongholds in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_6"
|
||||
title: "Minecraft Achievements"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Common Achievements"
|
||||
content_blocks:
|
||||
- "Minecraft has various achievements that players can earn by completing specific tasks."
|
||||
- "Common achievements include 'Taking Inventory,' 'Getting Wood,' and 'Benchmarking.'"
|
||||
tokens_for_ai: "Explain what achievements are in Minecraft and describe some common ones in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some common achievements in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about common achievements in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about common achievements. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on common achievements."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of common achievements in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Rare Achievements"
|
||||
content_blocks:
|
||||
- "Minecraft also has rare achievements that are more challenging to earn."
|
||||
- "Rare achievements include 'The End,' 'Beaconator,' and 'Adventuring Time.'"
|
||||
tokens_for_ai: "Explain what rare achievements are in Minecraft and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some rare achievements in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about rare achievements in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about rare achievements. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on rare achievements."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of rare achievements in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_7"
|
||||
title: "Minecraft Redstone"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "What is Redstone?"
|
||||
content_blocks:
|
||||
- "Redstone is a special material in Minecraft that can be used to create circuits and machines."
|
||||
- "It allows players to build complex contraptions like doors, traps, and automated farms."
|
||||
tokens_for_ai: "Explain what Redstone is in Minecraft and its uses in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "What is Redstone and what can you do with it in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You understand what Redstone is and its uses in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of Redstone. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Redstone."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Redstone in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Basic Redstone Contraptions"
|
||||
content_blocks:
|
||||
- "Some basic Redstone contraptions include pressure plates, levers, and buttons."
|
||||
- "These can be used to create simple machines like doors that open automatically or lights that turn on with a switch."
|
||||
tokens_for_ai: "Explain some basic Redstone contraptions in Minecraft and their uses in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some basic Redstone contraptions and their uses in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about basic Redstone contraptions and their uses in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of basic Redstone contraptions. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on basic Redstone contraptions."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of basic Redstone contraptions in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_8"
|
||||
title: "Minecraft Updates"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Major Updates"
|
||||
content_blocks:
|
||||
- "Minecraft receives regular updates that add new features, blocks, and mobs to the game."
|
||||
- "Some major updates include the 'Nether Update,' 'Caves & Cliffs Update,' and 'Village & Pillage Update.'"
|
||||
tokens_for_ai: "Explain what major updates are in Minecraft and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you name some major updates in Minecraft?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know about major updates in Minecraft."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about major updates. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on major updates."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of major updates in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "New Features"
|
||||
content_blocks:
|
||||
- "Each major update introduces new features to Minecraft, such as new biomes, mobs, and blocks."
|
||||
- "These features enhance the gameplay experience and provide new challenges and opportunities for players."
|
||||
tokens_for_ai: "Explain what new features are introduced in Minecraft updates and describe some of them in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe some new features introduced in Minecraft updates?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know about new features introduced in Minecraft updates."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of new features. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on new features."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of new features in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_9"
|
||||
title: "Minecraft Community"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Minecraft Servers"
|
||||
content_blocks:
|
||||
- "Minecraft servers are online multiplayer worlds where players can join and play together."
|
||||
- "Servers offer various game modes, mini-games, and custom content created by the community."
|
||||
tokens_for_ai: "Explain what Minecraft servers are and their features in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe what Minecraft servers are and their features?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Great! You know what Minecraft servers are and their features."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You know a little about Minecraft servers. Let's learn more!"
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Minecraft servers."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Minecraft servers in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's answer them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- step_id: "step_2"
|
||||
title: "Minecraft Mods"
|
||||
content_blocks:
|
||||
- "Minecraft mods are modifications made by the community that add new features, items, and gameplay mechanics to the game."
|
||||
- "Mods can be downloaded and installed to enhance the Minecraft experience."
|
||||
tokens_for_ai: "Explain what Minecraft mods are and their uses in a friendly and engaging manner suitable for 7 to 13-year-olds. If any part of the user's answer is correct and on-topic, categorize it as 'correct'."
|
||||
question: "Can you describe what Minecraft mods are and their uses?"
|
||||
buckets:
|
||||
- correct
|
||||
- partial_understanding
|
||||
- off_topic
|
||||
- asking_clarifying_questions
|
||||
transitions:
|
||||
correct:
|
||||
content_blocks:
|
||||
- "Excellent! You know what Minecraft mods are and their uses."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide positive reinforcement and encourage the user to continue learning."
|
||||
partial_understanding:
|
||||
content_blocks:
|
||||
- "You have a partial understanding of Minecraft mods. Let's clarify a few points."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Provide additional information to clarify the user's understanding in a friendly and supportive manner."
|
||||
off_topic:
|
||||
content_blocks:
|
||||
- "It seems like your response is off-topic. Let's try to stay focused on Minecraft mods."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Gently guide the user back to the topic of Minecraft mods in a supportive manner."
|
||||
asking_clarifying_questions:
|
||||
content_blocks:
|
||||
- "I see you have some questions. Let's address them."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Answer the user's clarifying questions and provide additional information in a friendly and engaging manner."
|
||||
|
||||
- section_id: "section_10"
|
||||
title: "Congratulations!"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Well Done!"
|
||||
content_blocks:
|
||||
- "Congratulations on completing the Minecraft Trivia game!"
|
||||
- "You have learned a lot about Minecraft, including its gameplay, mobs, biomes, items, structures, achievements, Redstone, updates, and community."
|
||||
- "Remember, Minecraft is a game of creativity and exploration, so keep playing, building, and discovering new things."
|
||||
- "We are proud of your dedication and hard work. Well done!"
|
||||
|
||||
|
|
@ -1,866 +0,0 @@
|
|||
import argparse
|
||||
import yaml
|
||||
import json
|
||||
import random
|
||||
import os
|
||||
import sys
|
||||
from openai import OpenAI
|
||||
|
||||
# Add parent directory to path to import activity_utils
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
# Import activity utilities for v2.0 features
|
||||
from activity_utils import (
|
||||
render_template,
|
||||
check_conditions,
|
||||
filter_content_blocks,
|
||||
resolve_conditional_navigation,
|
||||
select_weighted_random,
|
||||
get_progressive_hint,
|
||||
create_template_context,
|
||||
)
|
||||
|
||||
# Global model-client mapping
|
||||
MODEL_CLIENT_MAP = {}
|
||||
|
||||
|
||||
def get_client_for_endpoint(endpoint, api_key):
|
||||
"""Create OpenAI client for any endpoint"""
|
||||
return OpenAI(api_key=api_key, base_url=endpoint)
|
||||
|
||||
|
||||
def initialize_model_map():
|
||||
"""Initialize the model-client mapping from environment variables"""
|
||||
# Load endpoints from environment variables
|
||||
for i in range(1000): # Support up to 1000 endpoints
|
||||
endpoint_key = f"MODEL_ENDPOINT_{i}"
|
||||
api_key_key = f"MODEL_API_KEY_{i}"
|
||||
|
||||
endpoint = os.getenv(endpoint_key)
|
||||
api_key = os.getenv(api_key_key)
|
||||
|
||||
if endpoint and api_key:
|
||||
try:
|
||||
client = get_client_for_endpoint(endpoint, api_key)
|
||||
# Query endpoint for available models
|
||||
try:
|
||||
response = client.models.list()
|
||||
model_list = response.data
|
||||
print(
|
||||
f"[DEBUG] {endpoint} returned models: {[m.id for m in model_list]}"
|
||||
)
|
||||
for m in model_list:
|
||||
model_id = m.id
|
||||
if model_id and model_id not in MODEL_CLIENT_MAP:
|
||||
MODEL_CLIENT_MAP[model_id] = (client, endpoint)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Warning: Could not list models for endpoint '{endpoint}': {e}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to initialize endpoint {endpoint}: {e}")
|
||||
|
||||
|
||||
def get_openai_client_and_model(model_name=None):
|
||||
"""Get OpenAI client and model name
|
||||
|
||||
Supports both direct model names and MODEL_X environment variable references.
|
||||
If model_name is MODEL_1, MODEL_2, etc., looks up from environment.
|
||||
"""
|
||||
# Handle MODEL_X references
|
||||
if model_name and model_name.startswith("MODEL_"):
|
||||
# Extract the number from MODEL_X
|
||||
try:
|
||||
model_num = model_name.split("_")[1]
|
||||
endpoint_key = f"MODEL_ENDPOINT_{model_num}"
|
||||
api_key_key = f"MODEL_API_KEY_{model_num}"
|
||||
|
||||
endpoint = os.getenv(endpoint_key)
|
||||
api_key = os.getenv(api_key_key)
|
||||
|
||||
if endpoint and api_key:
|
||||
client = get_client_for_endpoint(endpoint, api_key)
|
||||
|
||||
# Look up actual model name from MODEL_CLIENT_MAP for this endpoint
|
||||
actual_model = None
|
||||
for model_id, (registered_client, base_url) in MODEL_CLIENT_MAP.items():
|
||||
if base_url == endpoint:
|
||||
actual_model = model_id
|
||||
break
|
||||
|
||||
if actual_model:
|
||||
return client, actual_model
|
||||
else:
|
||||
# Fallback: query endpoint for models if not in map yet
|
||||
try:
|
||||
response = client.models.list()
|
||||
if response.data:
|
||||
actual_model = response.data[0].id
|
||||
print(
|
||||
f"[DEBUG] Using first model from {endpoint}: {actual_model}"
|
||||
)
|
||||
return client, actual_model
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not query models from {endpoint}: {e}")
|
||||
|
||||
# Final fallback
|
||||
print(
|
||||
f"Warning: No models found for {endpoint}, using 'model' as fallback"
|
||||
)
|
||||
return client, "model"
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to load {model_name}: {e}, falling back to default")
|
||||
|
||||
# Default to MODEL_1 (Hermes)
|
||||
if not model_name:
|
||||
return get_openai_client_and_model("MODEL_1")
|
||||
|
||||
# Try to find client for specific model name
|
||||
for stored_model, (client, base_url) in MODEL_CLIENT_MAP.items():
|
||||
if model_name in stored_model or stored_model == model_name:
|
||||
return client, model_name
|
||||
|
||||
# Fallback to first available client
|
||||
if MODEL_CLIENT_MAP:
|
||||
client, _ = next(iter(MODEL_CLIENT_MAP.values()))
|
||||
return client, model_name
|
||||
|
||||
# Final fallback to environment or default OpenAI
|
||||
api_key = os.getenv("OPENAI_API_KEY", "dummy-key")
|
||||
endpoint = os.getenv("MODEL_ENDPOINT_0", "https://api.openai.com/v1")
|
||||
|
||||
client = get_client_for_endpoint(endpoint, api_key)
|
||||
return client, model_name
|
||||
|
||||
|
||||
# Initialize the model mapping on startup
|
||||
initialize_model_map()
|
||||
|
||||
|
||||
# Load the YAML activity file
|
||||
def load_yaml_activity(file_path):
|
||||
with open(file_path, "r") as file:
|
||||
return yaml.safe_load(file)
|
||||
|
||||
|
||||
# Categorize the user's response
|
||||
def categorize_response(question, response, buckets, tokens_for_ai, model="MODEL_1"):
|
||||
bucket_list = ", ".join([str(bucket) for bucket in buckets])
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"{tokens_for_ai} Categorize the following response into one of the following buckets: {bucket_list}. Return ONLY a bucket label.",
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Question: {question}\nResponse: {response}\n\nCategory:",
|
||||
},
|
||||
]
|
||||
|
||||
try:
|
||||
client, model_name = get_openai_client_and_model(model)
|
||||
completion = client.chat.completions.create(
|
||||
model=model_name,
|
||||
messages=messages,
|
||||
max_tokens=5,
|
||||
temperature=0,
|
||||
)
|
||||
category = (
|
||||
completion.choices[0].message.content.strip().lower().replace(" ", "_")
|
||||
)
|
||||
return category
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
# Generate AI feedback
|
||||
def generate_ai_feedback(
|
||||
category, question, user_response, tokens_for_ai, metadata, model="MODEL_1"
|
||||
):
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"{tokens_for_ai} Generate a human-readable feedback message based on the following:",
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Question: {question}\nResponse: {user_response}\nCategory: {category},\nMetadata: {metadata}",
|
||||
},
|
||||
]
|
||||
|
||||
try:
|
||||
client, model_name = get_openai_client_and_model(model)
|
||||
completion = client.chat.completions.create(
|
||||
model=model_name, messages=messages, max_tokens=250, temperature=0.7
|
||||
)
|
||||
feedback = completion.choices[0].message.content.strip()
|
||||
return feedback
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
# Provide feedback based on the category (legacy single feedback system)
|
||||
def provide_feedback(
|
||||
transition,
|
||||
category,
|
||||
question,
|
||||
user_response,
|
||||
user_language,
|
||||
tokens_for_ai,
|
||||
metadata,
|
||||
model="MODEL_1",
|
||||
):
|
||||
feedback = ""
|
||||
if "ai_feedback" in transition:
|
||||
tokens_for_ai += f" Provide the feedback in {user_language}. {transition['ai_feedback'].get('tokens_for_ai', '')}."
|
||||
|
||||
# Filter metadata for feedback if metadata_feedback_filter is specified
|
||||
feedback_metadata = metadata
|
||||
if "metadata_feedback_filter" in transition:
|
||||
filter_keys = transition["metadata_feedback_filter"]
|
||||
feedback_metadata = {k: v for k, v in metadata.items() if k in filter_keys}
|
||||
|
||||
ai_feedback = generate_ai_feedback(
|
||||
category, question, user_response, tokens_for_ai, feedback_metadata, model
|
||||
)
|
||||
feedback += f"\n\nAI Feedback: {ai_feedback}"
|
||||
|
||||
return feedback
|
||||
|
||||
|
||||
# Provide feedback using multiple prompts (new system)
|
||||
def provide_feedback_prompts(
|
||||
transition,
|
||||
category,
|
||||
question,
|
||||
feedback_prompts,
|
||||
user_response,
|
||||
user_language,
|
||||
metadata,
|
||||
legacy_tokens_for_ai="",
|
||||
model="MODEL_1",
|
||||
):
|
||||
"""Generate feedback from multiple prompts"""
|
||||
feedback_messages = []
|
||||
|
||||
# Add user_response to metadata for filtering purposes
|
||||
full_metadata = metadata.copy()
|
||||
full_metadata["user_response"] = user_response
|
||||
|
||||
for prompt in feedback_prompts:
|
||||
prompt_name = prompt.get("name", "unnamed")
|
||||
tokens_for_ai = prompt.get("tokens_for_ai", "")
|
||||
|
||||
# Apply per-prompt metadata filtering if specified
|
||||
prompt_metadata = full_metadata
|
||||
if "metadata_filter" in prompt:
|
||||
filter_keys = prompt["metadata_filter"]
|
||||
prompt_metadata = {
|
||||
k: v for k, v in full_metadata.items() if k in filter_keys
|
||||
}
|
||||
|
||||
# Combine legacy tokens with prompt-specific tokens
|
||||
if legacy_tokens_for_ai:
|
||||
tokens_for_ai = legacy_tokens_for_ai + " " + tokens_for_ai
|
||||
|
||||
# Add language instruction
|
||||
tokens_for_ai += f" Provide the feedback in {user_language}."
|
||||
|
||||
# Add transition-specific AI feedback if present
|
||||
if "ai_feedback" in transition:
|
||||
tokens_for_ai += f" {transition['ai_feedback'].get('tokens_for_ai', '')}"
|
||||
|
||||
# Determine user_response for this prompt based on metadata filtering
|
||||
filtered_user_response = user_response
|
||||
if (
|
||||
"metadata_filter" in prompt
|
||||
and "user_response" not in prompt["metadata_filter"]
|
||||
):
|
||||
filtered_user_response = "" # Remove user response if not in filter
|
||||
|
||||
ai_feedback = generate_ai_feedback(
|
||||
category,
|
||||
question,
|
||||
filtered_user_response,
|
||||
tokens_for_ai,
|
||||
prompt_metadata,
|
||||
model,
|
||||
)
|
||||
|
||||
# Only add feedback if it has content and isn't exactly the STFU token
|
||||
if ai_feedback and ai_feedback.strip() and ai_feedback.strip() != "STFU":
|
||||
feedback_messages.append(
|
||||
{"name": prompt_name, "content": ai_feedback.strip()}
|
||||
)
|
||||
|
||||
return feedback_messages
|
||||
|
||||
|
||||
def execute_processing_script(metadata, script):
|
||||
# Prepare the environment for the script
|
||||
# Use the same dict for both globals and locals to support comprehensions
|
||||
script_env = {
|
||||
"__builtins__": __builtins__,
|
||||
"metadata": metadata,
|
||||
"script_result": None,
|
||||
}
|
||||
|
||||
# Execute the script
|
||||
exec(script, script_env, script_env)
|
||||
|
||||
# Return the result from the script
|
||||
return script_env["script_result"]
|
||||
|
||||
|
||||
def get_next_section_and_step(activity_content, current_section_id, current_step_id):
|
||||
for section in activity_content["sections"]:
|
||||
if section["section_id"] == current_section_id:
|
||||
for i, step in enumerate(section["steps"]):
|
||||
if step["step_id"] == current_step_id:
|
||||
if i + 1 < len(section["steps"]):
|
||||
return section["section_id"], section["steps"][i + 1]["step_id"]
|
||||
else:
|
||||
# Move to the next section
|
||||
next_section_index = (
|
||||
activity_content["sections"].index(section) + 1
|
||||
)
|
||||
if next_section_index < len(activity_content["sections"]):
|
||||
next_section = activity_content["sections"][
|
||||
next_section_index
|
||||
]
|
||||
return (
|
||||
next_section["section_id"],
|
||||
next_section["steps"][0]["step_id"],
|
||||
)
|
||||
return None, None
|
||||
|
||||
|
||||
def translate_text(text, target_language, model="MODEL_1"):
|
||||
# Guard clause for default language
|
||||
if target_language.lower() == "english":
|
||||
return text
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"Translate the following text to {target_language}:",
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": text,
|
||||
},
|
||||
]
|
||||
|
||||
try:
|
||||
client, model_name = get_openai_client_and_model(model)
|
||||
completion = client.chat.completions.create(
|
||||
model=model_name, messages=messages, max_tokens=500, temperature=0.7
|
||||
)
|
||||
translation = completion.choices[0].message.content.strip()
|
||||
return translation
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
def simulate_activity(yaml_file_path):
|
||||
yaml_content = load_yaml_activity(yaml_file_path)
|
||||
max_attempts = yaml_content.get("default_max_attempts_per_step", 3)
|
||||
|
||||
# Get activity-level model defaults (default to MODEL_1 - Hermes)
|
||||
default_classifier_model = yaml_content.get("classifier_model", "MODEL_1")
|
||||
default_feedback_model = yaml_content.get("feedback_model", "MODEL_1")
|
||||
|
||||
current_section_id = yaml_content["sections"][0]["section_id"]
|
||||
current_step_id = yaml_content["sections"][0]["steps"][0]["step_id"]
|
||||
|
||||
metadata = {"language": "English"} # Default language
|
||||
|
||||
while current_section_id and current_step_id:
|
||||
print(
|
||||
f"\n\nCurrent section: {current_section_id}, Current step: {current_step_id}\n\n"
|
||||
)
|
||||
section = next(
|
||||
(
|
||||
s
|
||||
for s in yaml_content["sections"]
|
||||
if s["section_id"] == current_section_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
step = next(
|
||||
(s for s in section["steps"] if s["step_id"] == current_step_id), None
|
||||
)
|
||||
|
||||
# Get step-level model overrides (if specified), otherwise use activity defaults
|
||||
classifier_model = step.get("classifier_model", default_classifier_model)
|
||||
feedback_model = step.get("feedback_model", default_feedback_model)
|
||||
|
||||
# Get the user's language preference from metadata
|
||||
user_language = metadata.get("language", "English")
|
||||
|
||||
# Initialize attempts and max_attempts for this step
|
||||
attempts = 0
|
||||
step_max_attempts = step.get("max_attempts_per_step", max_attempts)
|
||||
|
||||
# Create template context for rendering
|
||||
context = create_template_context(
|
||||
metadata=metadata,
|
||||
current_attempt=attempts,
|
||||
max_attempts=step_max_attempts,
|
||||
current_section=current_section_id,
|
||||
current_step=current_step_id,
|
||||
username="User",
|
||||
)
|
||||
|
||||
# Translate and print all content blocks once per step (v2.0 with templates & conditionals)
|
||||
if "content_blocks" in step:
|
||||
# Filter and render content blocks
|
||||
filtered_blocks = filter_content_blocks(
|
||||
step["content_blocks"], metadata, context
|
||||
)
|
||||
if filtered_blocks:
|
||||
content = "\n\n".join(filtered_blocks)
|
||||
translated_content = translate_text(
|
||||
content, user_language, feedback_model
|
||||
)
|
||||
print(translated_content)
|
||||
|
||||
# Skip classification and feedback if there's no question
|
||||
if "question" not in step:
|
||||
current_section_id, current_step_id = get_next_section_and_step(
|
||||
yaml_content, current_section_id, current_step_id
|
||||
)
|
||||
continue
|
||||
|
||||
# Render template variables in question (v2.0)
|
||||
question = render_template(step["question"], context)
|
||||
translated_question = translate_text(question, user_language, feedback_model)
|
||||
print(f"\nQuestion: {translated_question}")
|
||||
|
||||
while attempts < step_max_attempts:
|
||||
# Update context with current attempt
|
||||
context = create_template_context(
|
||||
metadata=metadata,
|
||||
current_attempt=attempts + 1, # 1-indexed for display
|
||||
max_attempts=step_max_attempts,
|
||||
current_section=current_section_id,
|
||||
current_step=current_step_id,
|
||||
username="User",
|
||||
)
|
||||
|
||||
user_response = input("\nYour Response: ")
|
||||
|
||||
# Roll for random buckets BEFORE categorization
|
||||
triggered_random_buckets = []
|
||||
if "random_buckets" in step:
|
||||
for bucket_name, config in step["random_buckets"].items():
|
||||
probability = config.get("probability", 0)
|
||||
roll = random.random()
|
||||
if roll < probability:
|
||||
triggered_random_buckets.append(bucket_name)
|
||||
print(
|
||||
f"🎲 [RANDOM EVENT] '{bucket_name}' triggered! (rolled {roll:.3f} < {probability})"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"🎲 [RANDOM CHECK] '{bucket_name}' not triggered (rolled {roll:.3f} >= {probability})"
|
||||
)
|
||||
|
||||
# Execute pre-script if it exists (runs before categorization, with user_response available)
|
||||
if "pre_script" in step:
|
||||
print(f"DEBUG: Executing pre-script")
|
||||
# Add user_response to a temporary copy of metadata for pre_script
|
||||
temp_metadata = metadata.copy()
|
||||
temp_metadata["user_response"] = user_response
|
||||
pre_result = execute_processing_script(
|
||||
temp_metadata, step["pre_script"]
|
||||
)
|
||||
|
||||
# Update metadata with pre-script results
|
||||
for key, value in pre_result.get("metadata", {}).items():
|
||||
metadata[key] = value
|
||||
print(f"DEBUG: Pre-script completed, updated metadata")
|
||||
|
||||
category = categorize_response(
|
||||
question,
|
||||
user_response,
|
||||
step["buckets"],
|
||||
step["tokens_for_ai"],
|
||||
classifier_model,
|
||||
)
|
||||
print(f"\nCategory: {category}")
|
||||
|
||||
# Combine user's category with triggered random buckets
|
||||
# User's response is processed FIRST, then random events
|
||||
all_active_buckets = [category] + triggered_random_buckets
|
||||
print(f"📋 Processing buckets in order: {all_active_buckets}")
|
||||
|
||||
# Find transitions for all active buckets
|
||||
active_transitions = []
|
||||
for bucket in all_active_buckets:
|
||||
transition = None
|
||||
if bucket in step["transitions"]:
|
||||
transition = step["transitions"][bucket]
|
||||
elif str(bucket).isdigit() and int(bucket) in step["transitions"]:
|
||||
transition = step["transitions"][int(bucket)]
|
||||
else:
|
||||
# Try boolean conversion
|
||||
if str(bucket).lower() in ["yes", "true"]:
|
||||
bucket = True
|
||||
elif str(bucket).lower() in ["no", "false"]:
|
||||
bucket = False
|
||||
if bucket in step["transitions"]:
|
||||
transition = step["transitions"][bucket]
|
||||
|
||||
if transition:
|
||||
active_transitions.append((bucket, transition))
|
||||
else:
|
||||
print(f"⚠️ Warning: No transition found for bucket '{bucket}'")
|
||||
|
||||
# If no valid transitions found at all (not even for user's category), error
|
||||
if not active_transitions:
|
||||
print(
|
||||
f"\nError: No valid transition found for category '{category}'. Please try again."
|
||||
)
|
||||
continue
|
||||
|
||||
print(f"✓ Found {len(active_transitions)} transition(s) to process")
|
||||
|
||||
# Track temporary metadata keys across all transitions
|
||||
metadata_tmp_keys = []
|
||||
|
||||
# Track the final navigation target (use LAST transition's next_section_and_step)
|
||||
final_next_section_and_step = None
|
||||
|
||||
# Track counts_as_attempt (if ANY transition counts, then it counts)
|
||||
any_counts_as_attempt = False
|
||||
|
||||
# Process ALL active transitions in order
|
||||
for bucket_name, transition in active_transitions:
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Processing transition for bucket: '{bucket_name}'")
|
||||
print(f"{'='*60}")
|
||||
|
||||
# Check metadata conditions (v2.0 advanced conditions)
|
||||
if "metadata_conditions" in transition:
|
||||
conditions_met = check_conditions(
|
||||
metadata, transition["metadata_conditions"]
|
||||
)
|
||||
if not conditions_met:
|
||||
print(
|
||||
f"⚠️ Skipping '{bucket_name}' - metadata conditions not met"
|
||||
)
|
||||
print(f"Current Metadata: {json.dumps(metadata, indent=2)}")
|
||||
continue
|
||||
|
||||
# Print transition content blocks if they exist (v2.0 with templates & conditionals)
|
||||
if "content_blocks" in transition:
|
||||
# Create template context
|
||||
context = create_template_context(
|
||||
metadata=metadata,
|
||||
current_attempt=attempts,
|
||||
max_attempts=max_attempts,
|
||||
current_section=current_section_id,
|
||||
current_step=current_step_id,
|
||||
username="User",
|
||||
)
|
||||
|
||||
# Filter and render content blocks (supports conditional blocks and templates)
|
||||
filtered_blocks = filter_content_blocks(
|
||||
transition["content_blocks"], metadata, context
|
||||
)
|
||||
|
||||
if filtered_blocks:
|
||||
transition_content = "\n\n".join(filtered_blocks)
|
||||
translated_transition_content = translate_text(
|
||||
transition_content, user_language, feedback_model
|
||||
)
|
||||
print(translated_transition_content)
|
||||
|
||||
# Update metadata based on user actions
|
||||
if "metadata_add" in transition:
|
||||
for key, value in transition["metadata_add"].items():
|
||||
if value == "the-users-response":
|
||||
value = user_response
|
||||
elif isinstance(value, str):
|
||||
if value.startswith("n+random(") and value.endswith(")"):
|
||||
# Extract the range and apply the random increment
|
||||
range_values = value[9:-1].split(",")
|
||||
if len(range_values) == 2:
|
||||
x, y = map(int, range_values)
|
||||
value = metadata.get(key, 0) + random.randint(x, y)
|
||||
elif value.startswith("n+") or value.startswith("n-"):
|
||||
# Check if this is string concatenation (n+,value) or numeric operation (n+5)
|
||||
if value.startswith("n+,") or value.startswith("n-,"):
|
||||
# String concatenation: append/remove from existing value
|
||||
operation = value[:2] # "n+" or "n-"
|
||||
suffix = value[
|
||||
3:
|
||||
] # Everything after "n+," or "n-,"
|
||||
existing_value = metadata.get(key, "")
|
||||
if operation == "n+":
|
||||
# Append with comma separator if existing value is non-empty
|
||||
if existing_value:
|
||||
value = f"{existing_value},{suffix}"
|
||||
else:
|
||||
value = suffix
|
||||
elif operation == "n-":
|
||||
# Remove suffix from existing value
|
||||
if existing_value:
|
||||
parts = existing_value.split(",")
|
||||
parts = [p for p in parts if p != suffix]
|
||||
value = ",".join(parts)
|
||||
else:
|
||||
value = existing_value
|
||||
else:
|
||||
# Numeric operation: extract the numeric part c and apply the operation +/-
|
||||
try:
|
||||
c = int(value[2:])
|
||||
if value.startswith("n+"):
|
||||
value = metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = metadata.get(key, 0) - c
|
||||
except ValueError:
|
||||
print(
|
||||
f"Warning: Invalid numeric operation '{value}' for key '{key}'"
|
||||
)
|
||||
# Leave value as-is if parsing fails
|
||||
metadata[key] = value
|
||||
|
||||
if "metadata_tmp_add" in transition:
|
||||
for key, value in transition["metadata_tmp_add"].items():
|
||||
if value == "the-users-response":
|
||||
value = user_response
|
||||
elif isinstance(value, str):
|
||||
if value.startswith("n+random(") and value.endswith(")"):
|
||||
# Extract the range and apply the random increment
|
||||
range_values = value[9:-1].split(",")
|
||||
if len(range_values) == 2:
|
||||
x, y = map(int, range_values)
|
||||
value = random.randint(x, y)
|
||||
elif value.startswith("n+") or value.startswith("n-"):
|
||||
# Check if this is string concatenation (n+,value) or numeric operation (n+5)
|
||||
if value.startswith("n+,") or value.startswith("n-,"):
|
||||
# String concatenation: append/remove from existing value
|
||||
operation = value[:2] # "n+" or "n-"
|
||||
suffix = value[
|
||||
3:
|
||||
] # Everything after "n+," or "n-,"
|
||||
existing_value = metadata.get(key, "")
|
||||
if operation == "n+":
|
||||
# Append with comma separator if existing value is non-empty
|
||||
if existing_value:
|
||||
value = f"{existing_value},{suffix}"
|
||||
else:
|
||||
value = suffix
|
||||
elif operation == "n-":
|
||||
# Remove suffix from existing value
|
||||
if existing_value:
|
||||
parts = existing_value.split(",")
|
||||
parts = [p for p in parts if p != suffix]
|
||||
value = ",".join(parts)
|
||||
else:
|
||||
value = existing_value
|
||||
else:
|
||||
# Numeric operation: extract the numeric part c and apply the operation +/-
|
||||
try:
|
||||
c = int(value[2:])
|
||||
if value.startswith("n+"):
|
||||
value = metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = metadata.get(key, 0) - c
|
||||
except ValueError:
|
||||
print(
|
||||
f"Warning: Invalid numeric operation '{value}' for key '{key}'"
|
||||
)
|
||||
# Leave value as-is if parsing fails
|
||||
metadata[key] = value
|
||||
metadata_tmp_keys.append(key) # Track temporary keys
|
||||
|
||||
if "metadata_remove" in transition:
|
||||
for key in transition["metadata_remove"]:
|
||||
if key in metadata:
|
||||
del metadata[key]
|
||||
|
||||
# Handle metadata_clear - clear all metadata if set to True
|
||||
if (
|
||||
"metadata_clear" in transition
|
||||
and transition["metadata_clear"] == True
|
||||
):
|
||||
metadata.clear()
|
||||
|
||||
# Handle metadata_random
|
||||
if "metadata_random" in transition:
|
||||
random_key = random.choice(
|
||||
list(transition["metadata_random"].keys())
|
||||
)
|
||||
random_value = transition["metadata_random"][random_key]
|
||||
metadata[random_key] = random_value
|
||||
|
||||
if "metadata_tmp_random" in transition:
|
||||
random_key = random.choice(
|
||||
list(transition["metadata_tmp_random"].keys())
|
||||
)
|
||||
random_value = random.choice(
|
||||
transition["metadata_tmp_random"][random_key]
|
||||
)
|
||||
metadata[random_key] = random_value
|
||||
metadata_tmp_keys.append(random_key) # Track temporary keys
|
||||
|
||||
# Handle metadata_weighted_random (v2.0)
|
||||
if "metadata_weighted_random" in transition:
|
||||
for key, weighted_options in transition[
|
||||
"metadata_weighted_random"
|
||||
].items():
|
||||
selected_value = select_weighted_random(weighted_options)
|
||||
metadata[key] = selected_value
|
||||
|
||||
# Handle metadata_tmp_weighted_random (v2.0)
|
||||
if "metadata_tmp_weighted_random" in transition:
|
||||
for key, weighted_options in transition[
|
||||
"metadata_tmp_weighted_random"
|
||||
].items():
|
||||
selected_value = select_weighted_random(weighted_options)
|
||||
metadata[key] = selected_value
|
||||
metadata_tmp_keys.append(key)
|
||||
|
||||
# Execute the processing script if it exists
|
||||
if "processing_script" in step and transition.get(
|
||||
"run_processing_script", False
|
||||
):
|
||||
# Add user_response to metadata temporarily for processing script
|
||||
temp_metadata = metadata.copy()
|
||||
temp_metadata["user_response"] = user_response
|
||||
|
||||
result = execute_processing_script(
|
||||
temp_metadata, step["processing_script"]
|
||||
)
|
||||
|
||||
# Copy any changes back to main metadata (except user_response)
|
||||
for key, value in temp_metadata.items():
|
||||
if key != "user_response":
|
||||
metadata[key] = value
|
||||
metadata["processing_script_result"] = result
|
||||
metadata_tmp_keys.append("processing_script_result")
|
||||
|
||||
# Update metadata with results from the processing script
|
||||
for key, value in result.get("metadata", {}).items():
|
||||
metadata[key] = value
|
||||
|
||||
print(
|
||||
f"\n[Metadata after '{bucket_name}']: {json.dumps(metadata, indent=2)}"
|
||||
)
|
||||
|
||||
# Provide feedback for THIS bucket
|
||||
if "feedback_prompts" in step:
|
||||
# New multi-prompt system - legacy tokens get combined with each prompt
|
||||
multi_feedback_messages = provide_feedback_prompts(
|
||||
transition,
|
||||
bucket_name, # Use bucket_name instead of category
|
||||
question,
|
||||
step["feedback_prompts"],
|
||||
user_response,
|
||||
user_language,
|
||||
metadata,
|
||||
step.get(
|
||||
"feedback_tokens_for_ai", ""
|
||||
), # Pass legacy tokens to be combined
|
||||
feedback_model,
|
||||
)
|
||||
# Display feedback immediately for this bucket
|
||||
for feedback_msg in multi_feedback_messages:
|
||||
print(f"\n{feedback_msg['name']}: {feedback_msg['content']}")
|
||||
elif step.get("feedback_tokens_for_ai"):
|
||||
# Legacy single feedback system - only if no feedback_prompts
|
||||
feedback = provide_feedback(
|
||||
transition,
|
||||
bucket_name, # Use bucket_name instead of category
|
||||
question,
|
||||
user_response,
|
||||
user_language,
|
||||
step.get("feedback_tokens_for_ai", ""),
|
||||
metadata,
|
||||
feedback_model,
|
||||
)
|
||||
if feedback and feedback.strip():
|
||||
print(f"\nFeedback: {feedback}")
|
||||
|
||||
# Track navigation (LAST transition's next_section_and_step wins)
|
||||
if "next_section_and_step" in transition:
|
||||
final_next_section_and_step = transition["next_section_and_step"]
|
||||
print(f"🎯 Navigation target set to: {final_next_section_and_step}")
|
||||
|
||||
# Track counts_as_attempt (if ANY transition counts, it counts)
|
||||
if transition.get("counts_as_attempt", True):
|
||||
any_counts_as_attempt = True
|
||||
|
||||
# End of multi-bucket processing loop
|
||||
|
||||
# Check for progressive hints (v2.0)
|
||||
if "hints" in step:
|
||||
hint_context = create_template_context(
|
||||
metadata=metadata,
|
||||
current_attempt=attempts + 1, # Next attempt
|
||||
max_attempts=step_max_attempts,
|
||||
current_section=current_section_id,
|
||||
current_step=current_step_id,
|
||||
username="User",
|
||||
)
|
||||
hint = get_progressive_hint(step["hints"], attempts + 1, hint_context)
|
||||
if hint:
|
||||
translated_hint = translate_text(
|
||||
hint["text"], user_language, feedback_model
|
||||
)
|
||||
print(f"\n💡 Hint: {translated_hint}")
|
||||
# If hint doesn't count as attempt, adjust counting
|
||||
if not hint["counts_as_attempt"]:
|
||||
any_counts_as_attempt = False
|
||||
|
||||
# Check if we should break or continue attempting
|
||||
if category not in [
|
||||
"partial_understanding",
|
||||
"limited_effort",
|
||||
"asking_clarifying_questions",
|
||||
"set_language",
|
||||
"off_topic",
|
||||
]:
|
||||
break
|
||||
|
||||
# Increment attempts if ANY transition counted
|
||||
if any_counts_as_attempt:
|
||||
attempts += 1
|
||||
|
||||
if attempts == step_max_attempts:
|
||||
print("\nMaximum attempts reached. Moving to the next step.")
|
||||
|
||||
# Remove temporary metadata at the end of the step
|
||||
for key in metadata_tmp_keys:
|
||||
if key in metadata:
|
||||
del metadata[key]
|
||||
|
||||
# Use the final navigation target (from LAST processed transition)
|
||||
# v2.0: Resolve conditional navigation
|
||||
if final_next_section_and_step:
|
||||
resolved_navigation = resolve_conditional_navigation(
|
||||
final_next_section_and_step, metadata
|
||||
)
|
||||
if resolved_navigation:
|
||||
current_section_id, current_step_id = resolved_navigation.split(":")
|
||||
else:
|
||||
# No navigation specified, move to next step automatically
|
||||
current_section_id, current_step_id = get_next_section_and_step(
|
||||
yaml_content, current_section_id, current_step_id
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Simulate an activity.")
|
||||
parser.add_argument(
|
||||
"yaml_file_path",
|
||||
type=str,
|
||||
help="Path to the activity YAML file",
|
||||
default="activity0.yaml",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
simulate_activity(args.yaml_file_path)
|
||||
1440
static/css/style.css
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 4 KiB |
|
|
@ -1,12 +0,0 @@
|
|||
/**
|
||||
* Utility functions for the OpenCompletion application
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert a string to a URL-friendly slug
|
||||
* @param {string} str - The string to slugify
|
||||
* @returns {string} - The slugified string
|
||||
*/
|
||||
function slugify(str) {
|
||||
return str.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]+/g, '');
|
||||
}
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sign In - OpenCompletion</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
.auth-container {
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 40px;
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.logo {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.logo h1 {
|
||||
color: #667eea;
|
||||
margin: 0;
|
||||
font-size: 32px;
|
||||
}
|
||||
.logo p {
|
||||
color: #666;
|
||||
margin: 5px 0 0 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.auth-step {
|
||||
display: none;
|
||||
}
|
||||
.auth-step.active {
|
||||
display: block;
|
||||
}
|
||||
.auth-step h2 {
|
||||
margin-top: 0;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
.auth-step p {
|
||||
color: #666;
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.auth-step input {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
margin-bottom: 15px;
|
||||
border: 2px solid #e1e1e1;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.auth-step input:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
}
|
||||
.auth-step button {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 14px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.auth-step button:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.auth-step button.secondary-btn {
|
||||
background: #6c757d;
|
||||
}
|
||||
.error-message {
|
||||
color: #dc3545;
|
||||
font-size: 14px;
|
||||
margin-top: -10px;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.back-link {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.back-link a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
.back-link a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.success-icon {
|
||||
text-align: center;
|
||||
font-size: 64px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="auth-container">
|
||||
<div class="logo">
|
||||
<h1>🚀 OpenCompletion</h1>
|
||||
<p>Machine Learning Powered Collaboration</p>
|
||||
</div>
|
||||
|
||||
<!-- Step 1: Enter email -->
|
||||
<div id="auth-step-email" class="auth-step active">
|
||||
<h2>Sign In / Sign Up</h2>
|
||||
<p>Enter your email to receive a verification code</p>
|
||||
<input type="email" id="auth-email" placeholder="your@email.com" />
|
||||
<button onclick="sendOTP()">Send Code</button>
|
||||
<div id="auth-email-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Enter OTP -->
|
||||
<div id="auth-step-otp" class="auth-step">
|
||||
<h2>Enter Verification Code</h2>
|
||||
<p>We sent a 6-digit code to <strong><span id="auth-email-display"></span></strong></p>
|
||||
<input type="text" id="auth-otp" placeholder="123456" maxlength="6" />
|
||||
<button onclick="verifyOTP()">Verify</button>
|
||||
<button class="secondary-btn" onclick="backToEmailStep()">Back</button>
|
||||
<div id="auth-otp-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: Claim display name (new users only) -->
|
||||
<div id="auth-step-name" class="auth-step">
|
||||
<h2>Choose Display Name</h2>
|
||||
<p>Pick a unique display name (3-50 characters)</p>
|
||||
<input type="text" id="auth-display-name" placeholder="username" maxlength="50" />
|
||||
<button onclick="claimName()">Complete Sign Up</button>
|
||||
<div id="auth-name-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Success -->
|
||||
<div id="auth-step-success" class="auth-step">
|
||||
<div class="success-icon">✅</div>
|
||||
<h2>Success!</h2>
|
||||
<p>Welcome, <strong><span id="auth-success-name"></span></strong>!</p>
|
||||
<button onclick="redirectToChatRooms()">Go to Chat Rooms</button>
|
||||
</div>
|
||||
|
||||
<div class="back-link">
|
||||
<a href="/">← Back to Home</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let pendingEmail = '';
|
||||
|
||||
function showAuthStep(step) {
|
||||
document.querySelectorAll('.auth-step').forEach(el => el.classList.remove('active'));
|
||||
document.getElementById('auth-step-' + step).classList.add('active');
|
||||
clearAuthErrors();
|
||||
}
|
||||
|
||||
function clearAuthErrors() {
|
||||
document.querySelectorAll('.error-message').forEach(el => el.textContent = '');
|
||||
}
|
||||
|
||||
function backToEmailStep() {
|
||||
showAuthStep('email');
|
||||
}
|
||||
|
||||
function redirectToChatRooms() {
|
||||
window.location.href = '/chat/general';
|
||||
}
|
||||
|
||||
async function sendOTP() {
|
||||
const email = document.getElementById('auth-email').value.trim();
|
||||
const errorEl = document.getElementById('auth-email-error');
|
||||
|
||||
if (!email) {
|
||||
errorEl.textContent = 'Please enter your email';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/send-otp', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({email})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
pendingEmail = email;
|
||||
document.getElementById('auth-email-display').textContent = email;
|
||||
showAuthStep('otp');
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Failed to send code';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyOTP() {
|
||||
const otpCode = document.getElementById('auth-otp').value.trim();
|
||||
const errorEl = document.getElementById('auth-otp-error');
|
||||
|
||||
if (!otpCode) {
|
||||
errorEl.textContent = 'Please enter the code';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/verify-otp', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({email: pendingEmail, otp_code: otpCode})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
if (data.needs_display_name) {
|
||||
showAuthStep('name');
|
||||
} else {
|
||||
document.getElementById('auth-success-name').textContent = data.user.display_name;
|
||||
showAuthStep('success');
|
||||
}
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Invalid code';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
async function claimName() {
|
||||
const displayName = document.getElementById('auth-display-name').value.trim();
|
||||
const errorEl = document.getElementById('auth-name-error');
|
||||
|
||||
if (!displayName) {
|
||||
errorEl.textContent = 'Please enter a display name';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/claim-name', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({display_name: displayName})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
document.getElementById('auth-success-name').textContent = data.user.display_name;
|
||||
showAuthStep('success');
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Failed to claim name';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
// Allow Enter key to submit on each step
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('auth-email').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') sendOTP();
|
||||
});
|
||||
document.getElementById('auth-otp').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') verifyOTP();
|
||||
});
|
||||
document.getElementById('auth-display-name').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') claimName();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,679 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Chatroom{% endblock %}</title>
|
||||
|
||||
<!-- Meta description for SEO -->
|
||||
<meta name="description" content="{{ og_description|default('OpenCompletion - AI-powered collaborative chat rooms for machine learning') }}">
|
||||
|
||||
<!-- Open Graph meta tags for social sharing (Facebook, Discord, LinkedIn, etc.) -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="{{ og_title|default('OpenCompletion - AI-Powered Chat Rooms') }}">
|
||||
<meta property="og:description" content="{{ og_description|default('OpenCompletion - AI-powered collaborative chat rooms for machine learning') }}">
|
||||
<meta property="og:site_name" content="OpenCompletion">
|
||||
{% if og_image %}
|
||||
<meta property="og:image" content="{{ og_image }}">
|
||||
<meta property="og:image:alt" content="Preview image for {{ og_title|default('OpenCompletion') }}">
|
||||
{% else %}
|
||||
<meta property="og:image" content="{{ url_for('static', filename='images/og-default.png', _external=True) }}">
|
||||
<meta property="og:image:alt" content="OpenCompletion logo">
|
||||
{% endif %}
|
||||
|
||||
<!-- Twitter Card meta tags -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="{{ og_title|default('OpenCompletion - AI-Powered Chat Rooms') }}">
|
||||
<meta name="twitter:description" content="{{ og_description|default('OpenCompletion - AI-powered collaborative chat rooms for machine learning') }}">
|
||||
{% if og_image %}
|
||||
<meta name="twitter:image" content="{{ og_image }}">
|
||||
{% else %}
|
||||
<meta name="twitter:image" content="{{ url_for('static', filename='images/og-default.png', _external=True) }}">
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
// Set theme immediately to prevent flash
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('theme') || 'light';
|
||||
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Include highlight.js library for syntax highlighting -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
|
||||
<!-- Include highlight.js themes for light and dark modes -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github.min.css" id="highlight-theme-light">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github-dark.min.css" id="highlight-theme-dark" disabled>
|
||||
|
||||
<!-- Include socket.io for real-time bidirectional event-based communication -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.min.js"></script>
|
||||
<!-- Include marked.js for markdown parsing -->
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.2/marked.min.js"
|
||||
integrity="sha512-rfX4p3RNnxdwLT3wWP1K0NR3ztTobn+sISlT9WhxDDK00zNYbQ6MCHA5OHm0hqKAzEMXYCgFrp8iY/ER5MkXqA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer">
|
||||
</script>
|
||||
|
||||
<!-- Include DOMPurify to sanitize HTML and prevent XSS attacks -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/dompurify@2/dist/purify.min.js"></script>
|
||||
|
||||
<!-- Include utility functions -->
|
||||
<script src="{{ url_for('static', filename='js/utils.js') }}"></script>
|
||||
|
||||
<script>
|
||||
// Connect to the server using socket.io
|
||||
const socket = io();
|
||||
</script>
|
||||
|
||||
<!-- Link to the favicon -->
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
|
||||
<!-- Link to external stylesheet -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Hamburger button for mobile -->
|
||||
<button id="hamburger-button">☰</button>
|
||||
|
||||
<!-- Modal for room list and utility belt -->
|
||||
<div id="room-list-modal">
|
||||
<div id="room-list-modal-content">
|
||||
<button id="close-modal-button" onclick="closeModal()">×</button>
|
||||
<div id="utility-belt-mobile" class="utility-belt">
|
||||
<div id="model-chooser-mobile">
|
||||
<label for="model-select-mobile">Choose Model:</label>
|
||||
<select id="model-select-mobile">
|
||||
<option value="None">None</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="voice-chooser-mobile">
|
||||
<label for="voice-select-mobile">Choose Voice:</label>
|
||||
<select id="voice-select-mobile">
|
||||
<option value="onyx">Onyx</option>
|
||||
<option value="alloy">Alloy</option>
|
||||
<option value="echo">Echo</option>
|
||||
<option value="fable">Fable</option>
|
||||
<option value="nova">Nova</option>
|
||||
<option value="shimmer">Shimmer</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="theme-toggle-mobile">
|
||||
<button id="theme-toggle-btn-mobile" onclick="toggleTheme()" style="width: 100%; margin-top: 10px; background-color: #555; color: white; border: none; padding: 8px; border-radius: 4px; cursor: pointer;">
|
||||
Dark Mode
|
||||
</button>
|
||||
</div>
|
||||
<div id="auto-play-tts-mobile">
|
||||
<button id="auto-play-tts-btn-mobile" onclick="toggleAutoPlayTTS()" style="width: 100%; margin-top: 10px; background-color: #f44336; color: white; border: none; padding: 8px; border-radius: 4px; cursor: pointer;">
|
||||
Auto-Play TTS: OFF
|
||||
</button>
|
||||
</div>
|
||||
<div id="show-thinking-mobile">
|
||||
<button id="show-thinking-btn-mobile" onclick="toggleShowThinking()" style="width: 100%; margin-top: 10px; background-color: #4CAF50; color: white; border: none; padding: 8px; border-radius: 4px; cursor: pointer;">
|
||||
Thinking: ON
|
||||
</button>
|
||||
</div>
|
||||
<div id="activity-controls-mobile">
|
||||
<h3>Activities</h3>
|
||||
<div id="current-activity-info-mobile" style="display: none;">
|
||||
<p>Current Activity: <span id="current-activity-name-mobile"></span></p>
|
||||
<button id="cancel-activity-btn-mobile" onclick="cancelActivity()">Cancel Activity</button>
|
||||
</div>
|
||||
<div id="activity-list-section-mobile">
|
||||
<div style="display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 5px; margin-bottom: 5px;">
|
||||
<select id="activity-select-mobile" style="width: 100%; max-width: 100%; box-sizing: border-box;">
|
||||
<option value="">-- Select an Activity --</option>
|
||||
</select>
|
||||
<button id="refresh-activities-btn-mobile" onclick="refreshActivityList()">🔄</button>
|
||||
</div>
|
||||
<button id="load-activity-btn-mobile" onclick="loadSelectedActivityMobile()" style="margin-top: 5px;">Load Activity</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="user-lists-mobile">
|
||||
<div id="active-users-list">
|
||||
<h3>Active Users</h3>
|
||||
<ul id="active-users-mobile">
|
||||
<!-- Active users will be dynamically populated here -->
|
||||
</ul>
|
||||
</div>
|
||||
<div id="inactive-users-list">
|
||||
<h3>Inactive Users</h3>
|
||||
<ul id="inactive-users-mobile">
|
||||
<!-- Inactive users will be dynamically populated here -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="rooms-list-modal-content">
|
||||
<!-- Room list will be cloned here for mobile view -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chatroom list -->
|
||||
<div class="main-container">
|
||||
<div id="rooms-list">
|
||||
<!-- Create Room button with grid layout -->
|
||||
<div id="create-room-section" style="display: grid; gap: 10px; margin-bottom: 15px;">
|
||||
<a href="/">
|
||||
<button id="create-room-btn">Create Room</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Room tabs with dynamic active state based on current room -->
|
||||
<div id="room-tabs">
|
||||
<div class="room-tab {% if not current_room or not current_room.is_private %}active{% endif %}" id="public-rooms-tab" onclick="switchRoomTab('public')">
|
||||
🌍 Public
|
||||
</div>
|
||||
<div class="room-tab {% if current_room and current_room.is_private %}active{% endif %}" id="private-rooms-tab" onclick="switchRoomTab('private')">
|
||||
🔐 Private
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Private rooms section (show if viewing a private room) -->
|
||||
<div id="private-rooms-section" class="room-section" style="display: {% if current_room and current_room.is_private %}block{% else %}none{% endif %};">
|
||||
<div id="private-rooms-content">
|
||||
{% if user %}
|
||||
{% if private_rooms %}
|
||||
<ul class="rooms-list">
|
||||
{% for room in private_rooms %}
|
||||
<a href="{{ url_for('chat', room_name=room.name) }}">
|
||||
<li data-room-id="{{ room.id }}" class="private-room">
|
||||
<b>{{ room.name }}</b>
|
||||
{% if room.title %}
|
||||
<br />{{ room.title }}
|
||||
{% endif %}
|
||||
{% if room.get_active_users()|length %}
|
||||
<br /> {{ room.get_active_users()|length }} users
|
||||
{% endif %}
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="empty-state">No private rooms yet. Create one to get started!</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="auth-prompt">
|
||||
<p>🔒 Private rooms are only visible to you</p>
|
||||
<p>Sign in to create and access private rooms</p>
|
||||
<button class="auth-btn" onclick="showAuthModal()">Sign In / Sign Up</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Public rooms section (show if viewing a public room or no room) -->
|
||||
<div id="public-rooms-section" class="room-section" style="display: {% if not current_room or not current_room.is_private %}block{% else %}none{% endif %};">
|
||||
<ul id="rooms-list-ul" class="rooms-list">
|
||||
<!-- Loop through public rooms and create list items for each room -->
|
||||
{% for room in public_rooms %}
|
||||
<a href="{{ url_for('chat', room_name=room.name) }}">
|
||||
<li data-room-id="{{ room.id }}" class="public-room">
|
||||
<!-- Display the room title if available, otherwise the room name -->
|
||||
<b>{{ room.name }}</b>
|
||||
{% if room.title %}
|
||||
<br />{{ room.title }}
|
||||
{% endif %}
|
||||
{% if room.get_active_users()|length %}
|
||||
<br /> {{ room.get_active_users()|length }} users
|
||||
{% endif %}
|
||||
{% if user and room.owner_id == user.id %}
|
||||
<span class="owner-badge">👑 Owner</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<!-- Authentication Modal -->
|
||||
<div id="auth-modal" class="modal" style="display: none;">
|
||||
<div class="modal-content-auth">
|
||||
<button class="close-btn" onclick="closeAuthModal()">×</button>
|
||||
|
||||
<!-- Step 1: Enter email -->
|
||||
<div id="auth-step-email" class="auth-step">
|
||||
<h2>Sign In / Sign Up</h2>
|
||||
<p>Enter your email to receive a verification code</p>
|
||||
<input type="email" id="auth-email" placeholder="your@email.com" />
|
||||
<button onclick="sendOTP()">Send Code</button>
|
||||
<div id="auth-email-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Enter OTP -->
|
||||
<div id="auth-step-otp" class="auth-step" style="display: none;">
|
||||
<h2>Enter Verification Code</h2>
|
||||
<p>We sent a 6-digit code to <span id="auth-email-display"></span></p>
|
||||
<input type="text" id="auth-otp" placeholder="123456" maxlength="6" />
|
||||
<button onclick="verifyOTP()">Verify</button>
|
||||
<button class="secondary-btn" onclick="backToEmailStep()">Back</button>
|
||||
<div id="auth-otp-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: Claim display name (new users only) -->
|
||||
<div id="auth-step-name" class="auth-step" style="display: none;">
|
||||
<h2>Choose Display Name</h2>
|
||||
<p>Pick a unique display name (3-50 characters)</p>
|
||||
<input type="text" id="auth-display-name" placeholder="username" maxlength="50" />
|
||||
<button onclick="claimName()">Complete Sign Up</button>
|
||||
<div id="auth-name-error" class="error-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Success -->
|
||||
<div id="auth-step-success" class="auth-step" style="display: none;">
|
||||
<h2>✅ Success!</h2>
|
||||
<p>Welcome, <span id="auth-success-name"></span>!</p>
|
||||
<button onclick="closeAuthModalAndReload()">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Function to perform the search
|
||||
function performSearch() {
|
||||
const keywords = document.getElementById("search-keywords").value;
|
||||
if (!keywords) {
|
||||
alert("Please enter keywords to search.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigate to the search results page with the keywords as a query parameter
|
||||
window.location.href = `/search?keywords=${encodeURIComponent(keywords)}`;
|
||||
}
|
||||
|
||||
// Add event listener for keyword search the "Enter" key
|
||||
document.getElementById("search-keywords").addEventListener("keydown", function(event) {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
performSearch();
|
||||
}
|
||||
});
|
||||
|
||||
// Function to open the modal
|
||||
function openModal() {
|
||||
const modal = document.getElementById("room-list-modal");
|
||||
const modalContent = document.getElementById("room-list-modal-content");
|
||||
const closeButton = document.getElementById("close-modal-button");
|
||||
|
||||
// Clone the create room section and rooms list
|
||||
const createRoomSection = document.getElementById("create-room-section").cloneNode(true);
|
||||
const roomsList = document.getElementById("rooms-list-ul").cloneNode(true);
|
||||
|
||||
// Clear previous content and add all sections
|
||||
document.getElementById("rooms-list-modal-content").innerHTML = '';
|
||||
document.getElementById("rooms-list-modal-content").appendChild(createRoomSection);
|
||||
document.getElementById("rooms-list-modal-content").appendChild(roomsList);
|
||||
|
||||
modal.style.display = "flex";
|
||||
modalContent.style.display = "block";
|
||||
closeButton.style.display = "block";
|
||||
}
|
||||
|
||||
// Function to close the modal
|
||||
function closeModal() {
|
||||
const modal = document.getElementById("room-list-modal");
|
||||
const modalContent = document.getElementById("room-list-modal-content");
|
||||
const closeButton = document.getElementById("close-modal-button");
|
||||
modal.style.display = "none";
|
||||
modalContent.style.display = "none";
|
||||
closeButton.style.display = "none";
|
||||
}
|
||||
|
||||
// Function to update all room links (no query parameters needed)
|
||||
function updateRoomLinksWithCurrentParams() {
|
||||
// No longer needed - links don't use username in query string
|
||||
// Keeping function for compatibility
|
||||
}
|
||||
|
||||
// Add event listener to the hamburger button
|
||||
document.getElementById("hamburger-button").addEventListener("click", openModal);
|
||||
|
||||
// Theme switching functionality
|
||||
function toggleTheme() {
|
||||
const html = document.documentElement;
|
||||
const currentTheme = html.getAttribute('data-theme');
|
||||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
|
||||
// Update the data-theme attribute
|
||||
html.setAttribute('data-theme', newTheme);
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('theme', newTheme);
|
||||
|
||||
// Update button text for both desktop and mobile
|
||||
updateThemeButtonText(newTheme);
|
||||
|
||||
// Switch highlight.js theme
|
||||
updateHighlightTheme(newTheme);
|
||||
}
|
||||
|
||||
function updateHighlightTheme(theme) {
|
||||
const lightTheme = document.getElementById('highlight-theme-light');
|
||||
const darkTheme = document.getElementById('highlight-theme-dark');
|
||||
|
||||
if (theme === 'dark') {
|
||||
lightTheme.disabled = true;
|
||||
darkTheme.disabled = false;
|
||||
} else {
|
||||
lightTheme.disabled = false;
|
||||
darkTheme.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
function updateThemeButtonText(theme) {
|
||||
// Label shows the mode a click switches to.
|
||||
const label = theme === 'dark' ? 'Light Mode' : 'Dark Mode';
|
||||
const btn = document.getElementById('theme-toggle-btn');
|
||||
const btnMobile = document.getElementById('theme-toggle-btn-mobile');
|
||||
if (btn) btn.textContent = label;
|
||||
if (btnMobile) btnMobile.textContent = label;
|
||||
}
|
||||
|
||||
// Apply saved theme on page load
|
||||
function applySavedTheme() {
|
||||
const savedTheme = localStorage.getItem('theme') || 'light';
|
||||
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||
updateThemeButtonText(savedTheme);
|
||||
updateHighlightTheme(savedTheme);
|
||||
}
|
||||
|
||||
// Apply theme immediately (before DOMContentLoaded to prevent flash)
|
||||
applySavedTheme();
|
||||
|
||||
// Populate the mobile model dropdown dynamically
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
const modelSelectMobile = document.getElementById("model-select-mobile");
|
||||
|
||||
// Ensure theme button text is correct on page load
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
|
||||
updateThemeButtonText(currentTheme);
|
||||
|
||||
// Function to populate the dropdown
|
||||
function populateModelDropdown(models) {
|
||||
while (modelSelectMobile.options.length > 1) {
|
||||
modelSelectMobile.remove(1);
|
||||
}
|
||||
models.forEach(modelId => {
|
||||
const option = document.createElement('option');
|
||||
option.value = modelId;
|
||||
option.textContent = modelId;
|
||||
modelSelectMobile.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
// Memoization with localStorage (1-minute cache)
|
||||
const cacheKey = 'modelList';
|
||||
const cacheExpirationKey = 'modelListExpiration';
|
||||
const cacheDuration = 60 * 1000; // 1 minute in milliseconds
|
||||
|
||||
const cachedData = localStorage.getItem(cacheKey);
|
||||
const cachedExpiration = localStorage.getItem(cacheExpirationKey);
|
||||
|
||||
if (cachedData && cachedExpiration && Date.now() < parseInt(cachedExpiration)) {
|
||||
const models = JSON.parse(cachedData);
|
||||
populateModelDropdown(models);
|
||||
} else {
|
||||
fetch('/models')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const models = data.models;
|
||||
populateModelDropdown(models);
|
||||
localStorage.setItem(cacheKey, JSON.stringify(models));
|
||||
localStorage.setItem(cacheExpirationKey, Date.now() + cacheDuration);
|
||||
})
|
||||
.catch(error => console.error("Error fetching models:", error));
|
||||
}
|
||||
});
|
||||
|
||||
// Room tab switching
|
||||
function switchRoomTab(tab) {
|
||||
const publicTab = document.getElementById('public-rooms-tab');
|
||||
const privateTab = document.getElementById('private-rooms-tab');
|
||||
const publicSection = document.getElementById('public-rooms-section');
|
||||
const privateSection = document.getElementById('private-rooms-section');
|
||||
|
||||
if (tab === 'public') {
|
||||
publicTab.classList.add('active');
|
||||
privateTab.classList.remove('active');
|
||||
publicSection.style.display = 'block';
|
||||
privateSection.style.display = 'none';
|
||||
} else {
|
||||
privateTab.classList.add('active');
|
||||
publicTab.classList.remove('active');
|
||||
privateSection.style.display = 'block';
|
||||
publicSection.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Authentication modal functions
|
||||
let pendingEmail = '';
|
||||
|
||||
function showAuthModal() {
|
||||
document.getElementById('auth-modal').style.display = 'flex';
|
||||
showAuthStep('email');
|
||||
}
|
||||
|
||||
function closeAuthModal() {
|
||||
document.getElementById('auth-modal').style.display = 'none';
|
||||
clearAuthErrors();
|
||||
}
|
||||
|
||||
function closeAuthModalAndReload() {
|
||||
closeAuthModal();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function showAuthStep(step) {
|
||||
document.querySelectorAll('.auth-step').forEach(el => el.style.display = 'none');
|
||||
document.getElementById('auth-step-' + step).style.display = 'block';
|
||||
clearAuthErrors();
|
||||
}
|
||||
|
||||
function clearAuthErrors() {
|
||||
document.querySelectorAll('.error-message').forEach(el => el.textContent = '');
|
||||
}
|
||||
|
||||
function backToEmailStep() {
|
||||
showAuthStep('email');
|
||||
}
|
||||
|
||||
async function sendOTP() {
|
||||
const email = document.getElementById('auth-email').value.trim();
|
||||
const errorEl = document.getElementById('auth-email-error');
|
||||
|
||||
if (!email) {
|
||||
errorEl.textContent = 'Please enter your email';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/send-otp', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({email})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
pendingEmail = email;
|
||||
document.getElementById('auth-email-display').textContent = email;
|
||||
showAuthStep('otp');
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Failed to send code';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyOTP() {
|
||||
const otpCode = document.getElementById('auth-otp').value.trim();
|
||||
const errorEl = document.getElementById('auth-otp-error');
|
||||
|
||||
if (!otpCode) {
|
||||
errorEl.textContent = 'Please enter the code';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/verify-otp', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({email: pendingEmail, otp_code: otpCode})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
if (data.needs_display_name) {
|
||||
showAuthStep('name');
|
||||
} else {
|
||||
document.getElementById('auth-success-name').textContent = data.user.display_name;
|
||||
showAuthStep('success');
|
||||
}
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Invalid code';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
async function claimName() {
|
||||
const displayName = document.getElementById('auth-display-name').value.trim();
|
||||
const errorEl = document.getElementById('auth-name-error');
|
||||
|
||||
if (!displayName) {
|
||||
errorEl.textContent = 'Please enter a display name';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/auth/claim-name', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({display_name: displayName})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
document.getElementById('auth-success-name').textContent = data.user.display_name;
|
||||
showAuthStep('success');
|
||||
} else {
|
||||
errorEl.textContent = data.error || 'Failed to claim name';
|
||||
}
|
||||
} catch (error) {
|
||||
errorEl.textContent = 'Network error. Please try again.';
|
||||
}
|
||||
}
|
||||
|
||||
// Room management functions
|
||||
async function forkRoom(roomId) {
|
||||
const makePrivate = confirm('Fork as private room? (Cancel for public)');
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/rooms/${roomId}/fork`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({private: makePrivate})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
window.location.href = `/chat/${data.room.name}`;
|
||||
} else {
|
||||
alert(data.error || 'Failed to fork room');
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Network error. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
async function archiveRoom(roomId) {
|
||||
if (!confirm('Archive this room? It will be hidden but not deleted.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/rooms/${roomId}/archive`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
alert('Room archived successfully!');
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert(data.error || 'Failed to archive room');
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Network error. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRoom(roomId) {
|
||||
if (!confirm('Delete this room permanently? This cannot be undone!')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if current room is private by checking if we're in private section
|
||||
const currentRoomElement = document.querySelector(`[data-room-id="${roomId}"]`);
|
||||
const isPrivate = currentRoomElement ? currentRoomElement.classList.contains('private-room') : false;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/rooms/${roomId}/delete`, {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
// Navigate to the top room of the appropriate list (public or private)
|
||||
const roomList = isPrivate
|
||||
? document.querySelectorAll('#private-rooms-section .rooms-list li')
|
||||
: document.querySelectorAll('#public-rooms-section .rooms-list li');
|
||||
|
||||
// Find first room that isn't the deleted one
|
||||
let targetRoom = null;
|
||||
for (let room of roomList) {
|
||||
if (room.getAttribute('data-room-id') != roomId) {
|
||||
targetRoom = room;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetRoom) {
|
||||
// Navigate to the first available room in the list
|
||||
const link = targetRoom.closest('a');
|
||||
if (link) {
|
||||
window.location.href = link.href;
|
||||
} else {
|
||||
window.location.href = '/';
|
||||
}
|
||||
} else {
|
||||
// No other rooms available, go to home
|
||||
window.location.href = '/';
|
||||
}
|
||||
} else {
|
||||
alert(data.error || 'Failed to delete room');
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Network error. Please try again.');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Browse Rooms - OpenCompletion</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<script>
|
||||
// Set theme immediately to prevent flash
|
||||
(function() {
|
||||
const savedTheme = localStorage.getItem('theme') || 'light';
|
||||
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||
})();
|
||||
</script>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: var(--bg-page);
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
.header {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto 30px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
.header h1 {
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.header-actions {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.btn {
|
||||
background: linear-gradient(135deg, var(--gradient-start) 0%, var(--gradient-end) 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.btn-secondary {
|
||||
background: #6c757d;
|
||||
}
|
||||
.room-tabs {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto 20px;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: max-content;
|
||||
gap: 10px;
|
||||
border-bottom: 2px solid #e1e1e1;
|
||||
}
|
||||
.room-tab {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
color: var(--text-secondary);
|
||||
border-bottom: 3px solid transparent;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.room-tab:hover {
|
||||
color: var(--button-primary);
|
||||
}
|
||||
.room-tab:focus {
|
||||
outline: none;
|
||||
background: none;
|
||||
}
|
||||
.room-tab.active {
|
||||
color: var(--button-primary);
|
||||
border-bottom-color: var(--button-primary);
|
||||
font-weight: bold;
|
||||
}
|
||||
.rooms-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.room-section {
|
||||
display: none;
|
||||
}
|
||||
.room-section.active {
|
||||
display: block;
|
||||
}
|
||||
.rooms-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.room-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s, box-shadow 0.2s, background-color 0.3s ease;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: block;
|
||||
}
|
||||
.room-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.room-card-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.room-name {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: var(--button-primary);
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
.room-title {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
margin: 8px 0;
|
||||
line-height: 1.4;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.room-meta {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: max-content;
|
||||
gap: 15px;
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.room-meta-item {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: var(--text-muted);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.empty-state h3 {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 10px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.auth-prompt {
|
||||
background: #fff3cd;
|
||||
border: 1px solid #ffc107;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.auth-prompt button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.rooms-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.header {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.header-actions {
|
||||
grid-auto-flow: row;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>🚀 Browse Rooms</h1>
|
||||
<div class="header-actions">
|
||||
<a href="/" class="btn">🏠 Home</a>
|
||||
{% if user %}
|
||||
<a href="/profile" class="btn btn-secondary">👤 {{ user.display_name }}</a>
|
||||
{% else %}
|
||||
<a href="/auth" class="btn btn-secondary">🔐 Sign In</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="room-tabs">
|
||||
<button class="room-tab active" onclick="switchTab('public', this)">
|
||||
🌍 Public Rooms
|
||||
</button>
|
||||
<button class="room-tab" onclick="switchTab('private', this)">
|
||||
🔐 Private Rooms
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="rooms-container">
|
||||
<!-- Public Rooms -->
|
||||
<div id="public-section" class="room-section active">
|
||||
{% if public_rooms %}
|
||||
<div class="rooms-grid">
|
||||
{% for room in public_rooms %}
|
||||
<a href="{{ url_for('chat', room_name=room.name) }}" class="room-card">
|
||||
<div class="room-card-header">
|
||||
<h3 class="room-name">{{ room.name }}</h3>
|
||||
<span class="badge badge-public">Public</span>
|
||||
</div>
|
||||
{% if room.title %}
|
||||
<p class="room-title">{{ room.title }}</p>
|
||||
{% endif %}
|
||||
<div class="room-meta">
|
||||
<span class="room-meta-item">
|
||||
👥 {{ room.get_active_users()|length }} active
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<h3>No public rooms yet</h3>
|
||||
<p>Be the first to create one!</p>
|
||||
<a href="/" class="btn">Create a Room</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Private Rooms -->
|
||||
<div id="private-section" class="room-section">
|
||||
{% if user %}
|
||||
{% if private_rooms %}
|
||||
<div class="rooms-grid">
|
||||
{% for room in private_rooms %}
|
||||
<a href="{{ url_for('chat', room_name=room.name) }}" class="room-card">
|
||||
<div class="room-card-header">
|
||||
<h3 class="room-name">{{ room.name }}</h3>
|
||||
<span class="badge badge-private">Private</span>
|
||||
</div>
|
||||
{% if room.title %}
|
||||
<p class="room-title">{{ room.title }}</p>
|
||||
{% endif %}
|
||||
<div class="room-meta">
|
||||
<span class="room-meta-item">
|
||||
👥 {{ room.get_active_users()|length }} active
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<h3>No private rooms yet</h3>
|
||||
<p>Create your first private room!</p>
|
||||
<a href="/" class="btn">Create a Room</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="auth-prompt">
|
||||
<h3>🔒 Private rooms are only visible to you</h3>
|
||||
<p>Sign in to create and access your private rooms</p>
|
||||
<a href="/auth" class="btn">Sign In / Sign Up</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function switchTab(tab, element) {
|
||||
// Update tab buttons
|
||||
document.querySelectorAll('.room-tab').forEach(btn => {
|
||||
btn.classList.remove('active');
|
||||
});
|
||||
element.classList.add('active');
|
||||
|
||||
// Update sections
|
||||
document.querySelectorAll('.room-section').forEach(section => {
|
||||
section.classList.remove('active');
|
||||
});
|
||||
document.getElementById(tab + '-section').classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||