Add interactive routine wizard, slider controls, value persistence, and timer pause
All checks were successful
Deploy to VPS / deploy (push) Successful in 24s

- Interactive routine generation wizard with AI refinement loop (generate-draft,
  refine, save-draft endpoints + RoutineWizard modal component)
- Replace +/- stepper buttons with slider controls for reps/weight during workout
- Persist user-modified reps/weight across sets of the same exercise
- Add pause/resume by tapping timer dials, with back-button confirmation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Carlos Escalante
2026-03-20 22:29:06 -06:00
parent d7c1f8f677
commit 11e086166c
10 changed files with 613 additions and 130 deletions

View File

@@ -55,3 +55,47 @@ class KettlebellModule(dspy.Module):
kettlebell_module = KettlebellModule()
class RefineKettlebellSession(dspy.Signature):
"""Refine an existing kettlebell workout session based on user feedback.
You are given the current session and the user's feedback. Apply the requested changes
while keeping the rest of the session intact. Maintain proper exercise sequencing,
warm-up/cooldown structure, and ensure total work time still fits the target duration.
"""
current_session: str = dspy.InputField(desc="JSON representation of the current session")
user_feedback: str = dspy.InputField(desc="User's requested changes to the session")
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="Refined structured kettlebell session")
class KettlebellRefineModule(dspy.Module):
def __init__(self):
super().__init__()
self.refine = dspy.ChainOfThought(RefineKettlebellSession)
def forward(
self,
current_session: str,
user_feedback: str,
user_profile: str,
available_weights_kg: str,
focus: str,
duration_minutes: int,
):
return self.refine(
current_session=current_session,
user_feedback=user_feedback,
user_profile=user_profile,
available_weights_kg=available_weights_kg,
focus=focus,
duration_minutes=duration_minutes,
)
kettlebell_refine_module = KettlebellRefineModule()