"""End-to-end smoke test of the whole pipeline: Strava -> analyze -> render -> coach (Modal/vLLM) Run against your real Strava data: uv run python scripts/run_coach.py Run against built-in demo data (no Strava account needed): uv run python scripts/run_coach.py --demo Requires in your .env: LLM_BASE_URL (your Modal endpoint + /v1) LLM_MODEL (e.g. Qwen/Qwen3-1.7B) STRAVA_CLIENT_ID / STRAVA_CLIENT_SECRET / STRAVA_REFRESH_TOKEN (real mode only) """ import sys from datetime import datetime, timedelta from dotenv import load_dotenv from rate_my_run.client import StravaClient from rate_my_run.analytics import analyze from rate_my_run.render import summary_to_text from rate_my_run.coach import generate_report from rate_my_run.samples import demo_activities GOAL = "Build consistency: run 3 times per week" def main(): load_dotenv() # 1. Get activities — demo data or real Strava if "--demo" in sys.argv: activities = demo_activities() print(f"Using {len(activities)} demo activities.\n") else: client = StravaClient._from_env() after = int((datetime.now() - timedelta(weeks=8)).timestamp()) activities = client.get_activities(after=after, per_page=200) print(f"Fetched {len(activities)} activities from Strava.\n") # 2. Analyze + 3. render summary = analyze(activities) summary_text = summary_to_text(summary, goal=GOAL) print("=== TRAINING SUMMARY (this is what the model sees) ===") print(summary_text) # 4. Coach print("\n=== COACH REPORT (Sports Scientist) ===") report = generate_report(summary_text, personality="Sports Scientist") print(report) if __name__ == "__main__": main()