Shreya2005-2005's picture
fix: use clamp() in scoring formulas, remove score_range, use exclusive bounds
dd41132
|
Raw History Blame Contribute Delete
5.34 kB
metadata
title: Smart Study Session Optimizer
emoji: πŸ“š
colorFrom: blue
colorTo: green
sdk: docker
pinned: false

Smart Study Session Optimizer

Why I Built This

Okay so honestly this project started from a very relatable place β€” I used to study for 4-5 hours straight during exam prep, and by the third hour I was basically just staring at my notes without retaining anything. I knew I was supposed to take breaks but it felt like "wasting time". Turns out I was doing it completely wrong.

I came across some research on the Pomodoro Technique and ultradian rhythms, and I got curious: could you actually learn the optimal study break pattern using reinforcement learning? The environment models a simplified version of mental energy and focus, and lets an RL agent figure out when to grind and when to rest.

It's not a perfect simulation of human cognition (not even close), but it's a fun approximation and it passed all the hackathon criteria, so I'm calling it a win.


Project Structure

study-optimizer/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ models.py        # Pydantic models (Observation, Action, StepResult)
β”‚   β”œβ”€β”€ environment.py   # Core RL environment logic
β”‚   └── client.py        # HTTP client for the environment API
β”œβ”€β”€ server/
β”‚   └── app.py           # FastAPI server
β”œβ”€β”€ inference.py         # Main script: LLM agent runs an episode
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ requirements.txt
└── openenv.yaml         # OpenEnv spec compliance

How It Works

The environment simulates a study session. At each step, the agent sees:

  • Energy (0–100): how much mental stamina is left
  • Focus (0–100): current concentration level
  • Time studied: cumulative minutes of studying
  • Session elapsed: total minutes including breaks
  • Consecutive study minutes: streak without a break (focus drops fast here)
  • Break count: how many breaks taken
  • Productive minutes: minutes where focus was above 60

The agent picks one of 3 actions:

  • 0 β†’ Study (5 min, drains energy & focus)
  • 1 β†’ Short break (10 min, moderate recovery)
  • 2 β†’ Long break (20 min, full recovery but costs time)

The 3 Tasks

Task ID Goal Score Formula
survive_8_hours Keep energy > 0 for 480 min clamp(energy_remaining / 100, 0.01, 0.99)
maximize_productivity Max productive minutes in 240 min clamp(productive_minutes / 240, 0.01, 0.99)
smart_break_taker Only break when energy < 40% clamp(good_breaks / total_breaks, 0.01, 0.99)

Quick Start

1. Install dependencies

pip install -r requirements.txt

2. Run the server

uvicorn server.app:app --host 0.0.0.0 --port 7860 --reload

3. Run inference (LLM agent plays the game)

# Set env vars first
export API_BASE_URL="https://api.openai.com/v1"
export MODEL_NAME="gpt-4o-mini"
export HF_TOKEN="your_hf_token"

python inference.py --task maximize_productivity

4. Try it manually with curl

# Start an episode
curl -X POST http://localhost:7860/reset \
  -H "Content-Type: application/json" \
  -d '{"task_id": "maximize_productivity"}'

# Study for 5 minutes
curl -X POST http://localhost:7860/step \
  -H "Content-Type: application/json" \
  -d '{"action": 0}'

# Health check
curl http://localhost:7860/health

Docker

# Build
docker build -t study-optimizer .

# Run
docker run -p 7860:7860 study-optimizer

# With env vars for inference
docker run -p 7860:7860 \
  -e API_BASE_URL="https://api.openai.com/v1" \
  -e MODEL_NAME="gpt-4o-mini" \
  -e HF_TOKEN="your_token" \
  study-optimizer

Environment Variables

Variable Description Required
API_BASE_URL Base URL for OpenAI-compatible LLM API Yes (for inference)
MODEL_NAME Model identifier (e.g. gpt-4o-mini) Yes (for inference)
HF_TOKEN HuggingFace API token Yes (for HF Spaces)
PORT Server port (default: 7860) No

OpenEnv Compliance

This environment follows the OpenEnv spec:

  • POST /reset β†’ returns initial observation
  • POST /step β†’ takes action, returns {observation, reward, done, info}
  • GET /health β†’ returns {"status": "ok"}
  • GET /state β†’ returns full env state
  • openenv.yaml β†’ spec definition file

Reward Design

Reward at each step:

  • Studying with high energy + focus: +1.0
  • Studying with just energy (focus low): +0.3
  • Studying while exhausted: -0.5
  • Smart break (energy < 40): +0.5 to +1.0
  • Unnecessary break: -0.3 to -0.6
  • Terminal reward at end varies by task

The reward shaping is intentionally conservative β€” it's meant to guide the agent without being so prescriptive that it removes the need to learn anything interesting.


Known Limitations / TODOs

  • The energy drain model is simplified (doesn't account for circadian rhythms, caffeine, etc.)
  • No persistence β€” session state resets on server restart
  • Haven't tried training a proper PPO agent yet, only tested with LLM inference
  • Should add a WebSocket endpoint for real-time streaming

Built for the Meta PyTorch OpenEnv Hackathon by Scaler School of Technology