nicholasg1997
feat: add Local AI Running Coach with Gradio UI for personalized coaching reports
90b4eb9 | """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() | |