Files
healthy-fit/backend/app/ai/kettlebell.py
Carlos Escalante f279907ae3 Add supplements, kettlebell, calendar, push notifications, and PWA support
- Supplement tracking: CRUD endpoints, /today, /logs, Supplements page
- Kettlebell workouts: session tracking, analytics endpoint, ActiveSession page
- Calendar module: events CRUD, calendar components
- Push notifications: VAPID keys, PushSubscription model, APScheduler reminders,
  service worker with push/notificationclick handlers, Profile notifications UI
- PWA: vite-plugin-pwa, manifest, icons, service worker generation
- Frontend: TypeScript types, API modules, ConfirmModal, toast notifications
- Auth fixes: password hashing, nutrition endpoint auth
- CLAUDE.md: project documentation and development guide

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:57:03 -06:00

58 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import dspy
from pydantic import BaseModel, Field
class ExerciseBlock(BaseModel):
order: int = Field(description="Position in workout sequence")
name: str = Field(description="Exercise name")
description: str = Field(description="Brief description of the movement")
sets: int = Field(description="Number of sets")
reps: int = Field(description="Number of reps per set (0 if timed)")
duration_seconds: int = Field(description="Duration in seconds per set (0 if rep-based)")
weight_kg: float = Field(description="Prescribed weight in kg")
rest_seconds: int = Field(description="Rest time between sets in seconds")
coaching_tip: str = Field(description="Key coaching cue for this exercise")
class KettlebellSessionOutput(BaseModel):
reasoning: str = Field(description="Step-by-step reasoning for session design choices")
title: str = Field(description="Session title")
focus: str = Field(description="Session focus e.g. strength, conditioning, mobility")
total_duration_min: int = Field(description="Estimated total workout duration in minutes")
difficulty: str = Field(description="Difficulty level: beginner, intermediate, advanced")
exercises: list[ExerciseBlock] = Field(description="Ordered list of exercises in the session")
notes: str = Field(description="Coaching notes and any special instructions for the session")
class GenerateKettlebellSession(dspy.Signature):
"""Generate a personalized kettlebell workout session based on user profile and preferences.
Think step-by-step: assess user fitness level, pick movements appropriate to the focus and
difficulty, assign weights respecting progressive overload principles from available weights,
sequence exercises for proper warm-up and fatigue management, and ensure total work time
(sets × reps/duration + rest periods) fits within the requested duration.
"""
user_profile: str = dspy.InputField(desc="User details including age, weight, fitness level, and goals")
available_weights_kg: str = dspy.InputField(desc="Comma-separated list of available kettlebell weights in kg")
focus: str = dspy.InputField(desc="Session focus: strength, conditioning, mobility, fat loss, etc.")
duration_minutes: int = dspy.InputField(desc="Target session duration in minutes")
session: KettlebellSessionOutput = dspy.OutputField(desc="Complete structured kettlebell session")
class KettlebellModule(dspy.Module):
def __init__(self):
super().__init__()
self.generate = dspy.ChainOfThought(GenerateKettlebellSession)
def forward(self, user_profile: str, available_weights_kg: str, focus: str, duration_minutes: int):
return self.generate(
user_profile=user_profile,
available_weights_kg=available_weights_kg,
focus=focus,
duration_minutes=duration_minutes,
)
kettlebell_module = KettlebellModule()