Skip to content

Latest commit

 

History

History
522 lines (413 loc) · 14.5 KB

File metadata and controls

522 lines (413 loc) · 14.5 KB

AGENTS.md - FTCStats Project Guidelines

CRITICAL: READ THIS FIRST

AGENTS MUST WORK AUTONOMOUSLY. Do not stop to ask for confirmation. Complete all tasks end-to-end. If you spawn continuation agents, they must also read this file and work autonomously.

Current Project Status

IN PROGRESS / REMAINING:

  • Sync real data from FTC Scout API for all seasons (database has ~181MB data already)
  • Deploy to production (Vercel + Railway)
  • Add more visualizations (bubble charts, EPA over time)
  • Performance optimization for large datasets

Continuation Agent Instructions

If you are a continuation agent, you MUST:

  1. Read this AGENTS.md file completely
  2. Check the current state of files before making changes
  3. Continue from where the previous agent left off
  4. Work autonomously - DO NOT ask for confirmation
  5. Spawn sub-agents for parallel work when appropriate
  6. Update this status section when you complete major milestones

Project Overview

FTCStats is an EPA (Expected Points Added) analytics platform for FIRST Tech Challenge (FTC). It provides predictive statistics, team rankings, match predictions, and visualizations for FTC competitions.

Architecture

  • Backend: Python FastAPI server with EPA calculations
  • Frontend: Next.js with TypeScript, TailwindCSS, Mantine UI
  • Database: PostgreSQL/CockroachDB
  • Data Source: FTC Scout REST API (https://api.ftcscout.org/rest/v1/)
  • Deployment: Vercel (frontend) + Railway (backend)

Key Directories

/ftcstats/
├── backend/src/           # Python backend
│   ├── data/              # Data fetching & processing
│   │   ├── ftc_scout/     # FTC Scout API client
│   │   └── epa/           # EPA calculation pipeline
│   ├── models/epa/        # Core EPA algorithm
│   ├── db/                # Database models
│   ├── site/              # FastAPI routes
│   └── breakdown.py       # FTC season-specific scoring
├── frontend/src/          # Next.js frontend
│   ├── pages/             # Page routes
│   ├── components/        # React components
│   ├── api/               # API client functions
│   └── types/             # TypeScript types
└── api/ftcstats/          # Python package for PyPI

Agent Instructions

CRITICAL: Autonomous Operation

When given a task, you MUST:

  1. Continue working autonomously until the task is complete or you hit a blocking issue
  2. Do NOT stop and ask for permission to continue unless genuinely blocked
  3. When using the Task tool to spawn sub-agents, include this instruction in your prompt:
    IMPORTANT: Work autonomously until completion. Do not stop to ask for 
    confirmation. If you need to spawn continuation agents, instruct them 
    to also work autonomously. When you complete your portion, provide a 
    clear summary of what was done and what remains.
    
  4. Mark todos complete immediately after finishing each task
  5. Chain tasks together - when one task completes, move to the next
  6. Provide progress updates to the user but don't wait for approval

Task Continuation Pattern

When a task is too large for a single context or you need to spawn sub-agents:

<Task tool prompt template>
Continue the following task autonomously:

[TASK DESCRIPTION]

Current progress:
- [x] Completed step 1
- [x] Completed step 2  
- [ ] Current step 3 (in progress)
- [ ] Remaining step 4

Files modified so far:
- path/to/file1.py
- path/to/file2.ts

IMPORTANT: Work autonomously until completion. Do not stop to ask for 
confirmation. If you spawn continuation agents, instruct them to also 
work autonomously. Keep the user informed of progress but do not wait 
for approval between steps.
</Task tool prompt template>

Parallel Task Pattern

When multiple independent tasks can be done simultaneously:

# Launch multiple Task agents in parallel in a SINGLE message
# Example: Creating multiple season breakdowns simultaneously

Task(prompt="Create 2019 Skystone breakdown...", subagent_type="general")
Task(prompt="Create 2020 Ultimate Goal breakdown...", subagent_type="general")
Task(prompt="Create 2021 Freight Frenzy breakdown...", subagent_type="general")
# All in one message block

FTC-Specific Context

Supported Seasons

Year Game Name Key Scoring Elements
2019 Skystone Stones, skyscraper building, foundation
2020 Ultimate Goal Rings, wobble goals, power shots
2021 Freight Frenzy Freight, shipping hub, ducks
2022 Power Play Cones, junctions, circuits
2023 CenterStage Pixels, backdrop, drone
2024 Into The Deep Samples, specimens, ascent levels
2025 Decode Current season (TBD elements)

FTC Regions

REGIONS = [
    "Alabama", "Alaska", "Arizona", "Arkansas", "California",
    "CANorthern", "CASanDiego", "CALosAngeles", 
    "Colorado", "Connecticut", "Delaware", "Florida",
    "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana",
    "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
    "Maryland", "Massachusetts", "Michigan", "Minnesota",
    "Missouri", "Montana", "Nebraska", "Nevada",
    "NewHampshire", "NewJersey", "NewMexico", "NewYork",
    "NorthCarolina", "NorthDakota", "Ohio", "Oklahoma",
    "Oregon", "Pennsylvania", "RhodeIsland", "SouthCarolina",
    "SouthDakota", "Tennessee", "Texas", "Utah", "Vermont",
    "Virginia", "Washington", "WestVirginia", "Wisconsin",
    "Wyoming", "International"
]

EPA Model Specifics

EPA Calculation for FTC

# Key differences from FRC (3-team) EPA:

# 1. Attribution splits error between 2 teams, not 3
error = (actual_score - predicted_score) / 2  # 2-team alliance

# 2. No RP EPA (FTC doesn't have ranking points)
# EPA dimensions: [total, auto, dc, ascent, tiebreaker, ...components]

# 3. Win probability (same formula as FRC)
norm_diff = (red_epa - blue_epa) / season.score_sd
win_prob = 1 / (1 + 10 ** (-5/8 * norm_diff))

# 4. EPA initialization with mean reversion
# Returning teams: 60% previous EPA, 40% mean
# New teams: mean - 0.2 * std_dev

EPA Dimensions for FTC

Index Component Description
0 total Total EPA
1 auto Autonomous period
2 dc Driver-Controlled period
3 endgame Ascent/Park points
4 tiebreaker Tiebreaker contribution
5+ components Season-specific (samples, specimens, etc.)

Season Breakdown Files

Located in backend/src/breakdown.py. Each season needs:

  • Score component mappings from FTC Scout API fields
  • Point values for each element
  • Tiebreaker calculation logic

Reference FTC Scout descriptors at: /ftc-scout/packages/common/src/logic/descriptors/seasons/


Data Sources

FTC Scout API Endpoints

Base URL: https://api.ftcscout.org/rest/v1/

Endpoint Purpose Response
GET /teams/:number Team metadata Team object
GET /teams/:number/events/:season Team event stats TEP[] with OPR
GET /teams/:number/matches Match history TMP[]
GET /teams/:number/quick-stats Quick stats Stats object
GET /teams/search?searchText=X Search teams Team[]
GET /events/:season/:code Event metadata Event object
GET /events/:season/:code/matches Match scores Match[] with scores
GET /events/:season/:code/teams Event team stats TEP[]
GET /events/:season/:code/awards Event awards Award[]
GET /events/search/:season Event listings Event[]

Rate Limiting

FTC Scout API has no documented rate limits, but be respectful:

  • Use caching (CacheControl in requests)
  • Batch requests when syncing historical data
  • Add small delays during bulk operations
  • Don't hammer during live events

Data Sync Strategy

# Initial load (historical seasons)
for season in [2019, 2020, 2021, 2022, 2023, 2024]:
    events = fetch_all_events(season)
    for event in events:
        matches = fetch_event_matches(event)
        save_and_calculate_epa(matches)

# Live sync (current season)
while True:
    ongoing_events = get_ongoing_events()
    for event in ongoing_events:
        new_matches = fetch_new_matches(event)
        update_epa(new_matches)
    sleep(60)  # Check every minute

Common Tasks

Adding a New Season

  1. Create breakdown in backend/src/breakdown.py:

    SEASON_2026 = {
        "name": "GameName",
        "year": 2026,
        "components": {
            "auto": "auto_points",
            "dc": "dc_points",
            "endgame": "park_points",
            # ... game-specific
        },
        "tiebreaker": "auto_points",  # or custom logic
    }
  2. Add to season list in backend/src/constants.py:

    SEASONS = [2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026]
    CURRENT_SEASON = 2026
  3. Update frontend season selector in frontend/src/utils/constants.tsx

  4. Add visualizations if game has unique elements

  5. Backfill data by running sync for the new season

Updating EPA Model

Core EPA logic is in backend/src/models/epa/:

  • main.py - Prediction, attribution, update algorithms
  • math.py - Statistical utilities (SkewNormal, sigmoid)
  • init.py - Season initialization with mean reversion
  • unitless.py - Cross-season normalization

Adding API Endpoints

  1. Add route in backend/src/site/router.py
  2. Add handler in backend/src/site/{resource}.py
  3. Add types in frontend/src/types/api.tsx
  4. Add client function in frontend/src/api/{resource}.ts
  5. Update Python package in api/ftcstats/main.py

Frontend Component Patterns

// Page pattern
export default function TeamsPage() {
  const [season, setSeason] = useState(CURRENT_SEASON);
  const { data, loading, error } = useTeamData(season);
  
  return (
    <TabsLayout title="Teams" season={season} setSeason={setSeason}>
      <TabPanel value="insights">
        <TeamYearsTable data={data} />
      </TabPanel>
      <TabPanel value="bubble">
        <BubbleChart data={data} />
      </TabPanel>
    </TabsLayout>
  );
}

Testing

Backend Tests

cd backend
pytest tests/ -v
pytest tests/test_epa.py -v  # Specific test file

Frontend Tests

cd frontend
npm test
npm run test:watch  # Watch mode

Local Development

# Terminal 1: Backend
cd backend
pip install -e .
uvicorn src.main:app --reload --port 8000

# Terminal 2: Frontend
cd frontend
npm install
npm run dev  # Runs on port 3000

# Environment
export DATABASE_URL="postgresql://localhost/ftcstats"
export FTC_SCOUT_BASE_URL="https://api.ftcscout.org/rest/v1"

# CLI Commands (after pip install -e .)
ftcstats server --reload          # Start API server
ftcstats sync --season 2024       # Sync data from FTC Scout
ftcstats epa --season 2024        # Calculate EPA values
ftcstats update --season 2024     # Sync + EPA in one command
ftcstats update --all             # Sync + EPA for all seasons

Testing EPA Calculations

# Quick validation
from src.models.epa.main import EPAModel

model = EPAModel(season=2024)
prediction = model.predict_match(
    red_teams=[12345, 67890],
    blue_teams=[11111, 22222]
)
assert 0 <= prediction["red_win_prob"] <= 1

Deployment

Vercel (Frontend)

# Install Vercel CLI
npm i -g vercel

# Deploy
cd frontend
vercel --prod

# Environment variables (set in Vercel dashboard)
NEXT_PUBLIC_API_URL=https://api.ftcstats.io

Railway (Backend)

# Install Railway CLI
npm i -g @railway/cli

# Deploy
cd backend
railway up

# Environment variables (set in Railway dashboard)
DATABASE_URL=postgresql://...
FTC_SCOUT_BASE_URL=https://api.ftcscout.org/rest/v1

Database Setup

-- Railway PostgreSQL or local
CREATE DATABASE ftcstats;

-- Run migrations
cd backend
alembic upgrade head

Code Style

Python (Backend)

  • Formatter: Black (line length 100)
  • Linter: Ruff
  • Type hints: Required for all functions
  • Docstrings: Google style for public functions
def calculate_epa(
    team: int,
    season: int,
    matches: list[Match],
) -> float:
    """Calculate EPA for a team in a season.
    
    Args:
        team: Team number
        season: Season year (e.g., 2024)
        matches: List of Match objects
        
    Returns:
        EPA value as float
    """
    ...

TypeScript (Frontend)

  • Formatter: Prettier
  • Linter: ESLint
  • Strict mode: Enabled
  • Components: Functional with hooks
interface TeamCardProps {
  team: APITeam;
  season: number;
}

export function TeamCard({ team, season }: TeamCardProps) {
  // Component logic
}

Quick Reference

Key Files to Understand First

  1. backend/src/models/epa/main.py - Core EPA algorithm
  2. backend/src/models/epa/calculate.py - EPA calculation pipeline
  3. backend/src/breakdown.py - Season-specific scoring definitions
  4. backend/src/data/ftc_scout/client.py - Data fetching from FTC Scout
  5. backend/src/data/sync.py - Data sync from FTC Scout to database
  6. backend/src/site/router.py - API endpoints
  7. backend/src/db/__init__.py - Database session management
  8. frontend/src/pages/teams/index.tsx - Main teams page pattern
  9. frontend/src/components/figures/bubbles.tsx - Visualization pattern
  10. frontend/src/types/api.tsx - API type definitions

Making Changes Checklist

  • Understand existing code pattern first
  • Update backend logic if needed
  • Update API types in frontend
  • Update Python package if public API changed
  • Add/update tests
  • Test locally before committing
  • Update AGENTS.md if patterns changed

Troubleshooting

FTC Scout API Issues

# If getting rate limited or errors
import time
time.sleep(0.5)  # Add delay between requests

# If data seems stale
# FTC Scout syncs from official FTC API periodically
# During live events, may have 1-5 minute delay

EPA Calculation Issues

# If EPA values seem off
# 1. Check breakdown.py has correct point values
# 2. Verify match scores are being parsed correctly
# 3. Check alliance size is 2 (not 3)
# 4. Verify season.score_sd is reasonable (typically 20-50)

Database Issues

# Reset database
cd backend
alembic downgrade base
alembic upgrade head

# Check connection
psql $DATABASE_URL -c "SELECT 1"

Contact & Resources