File size: 6,183 Bytes
e803694
2223ccc
 
e803694
 
 
 
 
 
 
aae77cb
 
 
 
 
 
2223ccc
 
 
 
 
 
 
 
 
 
 
bcab4f1
2223ccc
 
 
e803694
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2223ccc
aae77cb
2223ccc
aae77cb
2223ccc
 
58cc220
bced719
 
 
 
 
 
 
2223ccc
 
aae77cb
2223ccc
 
 
 
 
 
bced719
2223ccc
 
bced719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2223ccc
bced719
 
2223ccc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f3c5ff1
2223ccc
 
 
 
 
 
 
 
 
aae77cb
 
 
 
e803694
aae77cb
e803694
aae77cb
e803694
aae77cb
e803694
aae77cb
e803694
aae77cb
 
 
 
 
e803694
aae77cb
e803694
aae77cb
 
 
 
e803694
aae77cb
 
 
 
e803694
aae77cb
 
 
 
 
e803694
aae77cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e803694
aae77cb
e803694
aae77cb
 
e803694
aae77cb
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import streamlit as st
from huggingface_hub import InferenceClient
import os

# -------------------------
# PAGE CONFIG
# -------------------------
st.set_page_config(page_title="FitPlan-AI", page_icon="💪")
st.title("💪 FitPlan-AI: Personalized Fitness Profile")

# -------------------------
# SESSION STATE FOR PAGE NAVIGATION
# -------------------------
if "page" not in st.session_state:
    st.session_state.page = "form"

# -------------------------
# LOAD HF CLIENT (CACHED)
# -------------------------
@st.cache_resource
def get_hf_client():
    hf_token = os.getenv("HF_TOKEN")

    if not hf_token:
        raise ValueError("HF_TOKEN not set in environment variables.")

    return InferenceClient(
        model="Qwen/Qwen2.5-7B-Instruct",
        token=hf_token
    )

# -------------------------
# BMI FUNCTIONS
# -------------------------
def calculate_bmi(weight, height_cm):
    height_m = height_cm / 100
    return round(weight / (height_m ** 2), 2)

def get_category(bmi):
    if bmi < 18.5:
        return "Underweight"
    elif bmi < 24.9:
        return "Normal"
    elif bmi < 29.9:
        return "Overweight"
    else:
        return "Obese"

# -------------------------
# PROMPT BUILDER (AGE ADDED)
# -------------------------
def build_prompt(name, age, height, weight, goal, level, equipment, bmi, bmi_status):
    equipment_list = ", ".join(equipment)

    prompt = f"""
You are a certified professional fitness trainer.
IMPORTANT:
- Do NOT write introduction.
- Do NOT write explanation.
- Do NOT give nutrition advice.
- Output ONLY the workout plan.
- Keep it concise.
Client Details:
Name: {name}
Age: {age}
Height: {height} cm
Weight: {weight} kg
BMI: {bmi} ({bmi_status})
Goal: {goal}
Fitness Level: {level}
Available Equipment: {equipment_list}
STRICT FORMAT:
Day 1:
Warm-up:
Main Workout (sets x reps):
Rest:
Cooldown:
Day 2:
Warm-up:
Main Workout (sets x reps):
Rest:
Cooldown:
Day 3:
Warm-up:
Main Workout (sets x reps):
Rest:
Cooldown:
Day 4:
Warm-up:
Main Workout (sets x reps):
Rest:
Cooldown:
Day 5:
Warm-up:
Main Workout (sets x reps):
Rest:
Cooldown:
Each day must contain 4–5 exercises only.
Keep total response under 900 words.
"""
    return prompt.strip()

# -------------------------
# MODEL QUERY
# -------------------------
def query_model(prompt):
    try:
        client = get_hf_client()

        response = client.chat_completion(
            messages=[
                {"role": "system", "content": "You are a certified professional fitness trainer."},
                {"role": "user", "content": prompt}
            ],
            max_tokens=1600,
            temperature=0.7,
            top_p=0.9
        )

        return response.choices[0].message.content.strip()

    except Exception as e:
        return f"⚠️ Model Error: {str(e)}"

# =========================
# PAGE 1 → FORM
# =========================
if st.session_state.page == "form":

    with st.form("fitness_form"):

        st.subheader("Personal Information")

        name = st.text_input("Full Name*", placeholder="Enter your name")

        age = st.number_input("Age*", min_value=18, max_value=65, step=1)

        col1, col2 = st.columns(2)
        with col1:
            height = st.number_input("Height (cm)*", min_value=1.0, step=0.1)
        with col2:
            weight = st.number_input("Weight (kg)*", min_value=1.0, step=0.1)

        st.subheader("Fitness Details")

        goal = st.selectbox(
            "Fitness Goal",
            ["Build Muscle", "Weight Loss", "Strength Gain", "Abs Building", "Flexibility"]
        )

        level = st.radio(
            "Fitness Level",
            ["Beginner", "Intermediate", "Advanced"]
        )

        equipment = st.multiselect(
            "Available Equipment",
            ["Dumbbells", "Resistance Band", "Yoga Mat", "No Equipment", 
             "Kettlebell", "Pull-up Bar"]
        )

        submit = st.form_submit_button("Submit Profile")

    # -------------------------
    # HANDLE SUBMISSION
    # -------------------------
    if submit:

        if not name:
            st.error("Please enter your name.")

        elif height <= 0 or weight <= 0:
            st.error("Please enter valid height and weight.")

        elif not equipment:
            st.error("Please select at least one equipment option.")

        else:
            # Store in session
            st.session_state.name = name
            st.session_state.age = age
            st.session_state.height = height
            st.session_state.weight = weight
            st.session_state.goal = goal
            st.session_state.level = level
            st.session_state.equipment = equipment

            st.session_state.page = "result"
            st.rerun()

# =========================
# PAGE 2 → RESULT
# =========================
if st.session_state.page == "result":

    name = st.session_state.name
    age = st.session_state.age
    height = st.session_state.height
    weight = st.session_state.weight
    goal = st.session_state.goal
    level = st.session_state.level
    equipment = st.session_state.equipment

    st.success("Profile Submitted Successfully!")

    bmi = calculate_bmi(weight, height)
    bmi_status = get_category(bmi)

    st.write("## 📋 Your Personal Information")
    st.write(f"**Name:** {name}")
    st.write(f"**Age:** {age}")
    st.write(f"**Height:** {height} cm")
    st.write(f"**Weight:** {weight} kg")
    st.write(f"**BMI:** {bmi} ({bmi_status})")
    st.write(f"**Goal:** {goal}")
    st.write(f"**Fitness Level:** {level}")
    st.write(f"**Equipment:** {', '.join(equipment)}")

    with st.spinner("Generating your 5-day workout plan..."):
        prompt = build_prompt(
            name=name,
            age=age,
            height=height,
            weight=weight,
            goal=goal,
            level=level,
            equipment=equipment,
            bmi=bmi,
            bmi_status=bmi_status
        )

        full_plan = query_model(prompt)

    st.subheader("🏋️ Your Personalized 5-Day Workout Plan")
    st.write(full_plan)

    if st.button("⬅️ Back"):
        st.session_state.page = "form"
        st.rerun()