Spaces:
Sleeping
Sleeping
File size: 12,622 Bytes
2b11126 5b2a369 aa746f1 2b11126 2164ce5 2b11126 f361d1e 2b11126 f361d1e 5b2a369 aa746f1 5b2a369 aa746f1 5b2a369 95e59aa 2b11126 95e59aa 5b2a369 2b11126 5b2a369 95e59aa 5b2a369 95e59aa 5b2a369 95e59aa 5b2a369 95e59aa 5b2a369 2b11126 95e59aa 2b11126 5b2a369 2b11126 5b2a369 2b11126 5b2a369 aa746f1 5b2a369 aa746f1 5b2a369 f361d1e 5b2a369 aa746f1 5b2a369 aa746f1 5b2a369 aa746f1 5b2a369 aa746f1 5b2a369 2b11126 aa746f1 | 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 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | import streamlit as st
from datetime import datetime
from prompt_builder import build_prompt
from model_api import query_model, test_api_connection, switch_model, set_ollama_mode
st.set_page_config(
page_title="FIT Plan AI - Milestone 2",
page_icon="πͺ",
layout="centered"
)
# Helper function to verify workout plan - MUST be defined before it's used
def verify_workout_plan(plan_text):
"""Check if the workout plan contains all 5 days"""
if not plan_text or plan_text.startswith("Error"):
return False, "No valid plan generated"
days_present = []
for i in range(1, 6):
if f"Day {i}" in plan_text:
days_present.append(i)
if len(days_present) == 5:
return True, "Complete 5-day plan"
else:
missing_days = set(range(1,6)) - set(days_present)
return False, f"Missing day(s): {', '.join(map(str, missing_days))}"
st.title("πͺ FIT Plan AI β Personalized Fitness Profile")
st.markdown("---")
# Test API connection on startup
if "api_status" not in st.session_state:
with st.spinner("Checking API connection..."):
api_ok, api_message = test_api_connection()
st.session_state.api_status = api_ok
st.session_state.api_message = api_message
# Show API status and model settings in sidebar
with st.sidebar:
st.header("π§ System Status")
if st.session_state.get("api_status", False):
st.success("β
API Connected")
else:
st.error(f"β API Error: {st.session_state.get('api_message', 'Unknown error')}")
st.info("Please set your HF_TOKEN environment variable")
# Add model selection
st.markdown("---")
st.header("π€ Model Settings")
# Model selection dropdown
model_options = {
"Llama 3.2 3B (Recommended)": "meta-llama/Llama-3.2-3B-Instruct",
"Llama 3.2 1B (Lightweight)": "meta-llama/Llama-3.2-1B-Instruct",
"Llama 3.3 70B (Best Quality)": "meta-llama/Llama-3.3-70B-Instruct",
"Fitness Assistant (Specialized)": "Soorya03/Llama-3.2-1B-FitnessAssistant",
"Mistral-7B (Original)": "mistralai/Mistral-7B-Instruct-v0.2"
}
selected_model = st.selectbox(
"Select Model",
options=list(model_options.keys()),
index=0
)
# Mode selection (API vs Local)
use_ollama = st.checkbox("Use Local Ollama (No API key needed)", value=False)
if st.button("Apply Settings"):
switch_model(model_options[selected_model])
set_ollama_mode(use_ollama)
# Retest connection with new settings
api_ok, api_message = test_api_connection()
st.session_state.api_status = api_ok
st.session_state.api_message = api_message
st.success(f"Switched to {selected_model}")
st.rerun()
if use_ollama:
st.info("π Make sure Ollama is running locally: 'ollama run llama3.2:3b'")
# Show current model info
st.markdown("---")
st.caption(f"Current: {selected_model}")
# Initialize session state
if "form_submitted" not in st.session_state:
st.session_state.form_submitted = False
if "workout_plan" not in st.session_state:
st.session_state.workout_plan = None
if "active_tab" not in st.session_state:
st.session_state.active_tab = "Profile"
# Create tabs for different sections
tab1, tab2 = st.tabs(["π Profile Setup", "ποΈ Workout Plan"])
# Tab 1: Profile Setup
with tab1:
with st.form("fitness_profile_form"):
st.header("Your Fitness Profile")
st.subheader("π€ Personal Information")
col1, col2 = st.columns(2)
with col1:
name = st.text_input("Full Name *")
height = st.number_input("Height (cm) *", min_value=1.0, max_value=300.0, value=170.0)
with col2:
age = st.number_input("Age *", min_value=10, max_value=120, value=25)
weight = st.number_input("Weight (kg) *", min_value=1.0, max_value=500.0, value=70.0)
gender = st.selectbox("Gender", ["Male", "Female", "Other"])
st.subheader("π― Fitness Details")
goal = st.selectbox(
"Fitness Goal *",
["Weight Loss", "Build Muscle", "Strength Gain", "Abs Building", "Flexibility"]
)
equipment = st.multiselect(
"Available Equipment *",
[
"Dumbbells",
"Resistance Bands",
"Barbell",
"Pull-up Bar",
"Treadmill",
"Kettlebells",
"Jump Rope",
"Yoga Mat",
"No Equipment (Bodyweight only)"
],
default=["No Equipment (Bodyweight only)"]
)
fitness_level = st.select_slider(
"Fitness Level *",
options=["Beginner", "Intermediate", "Advanced"],
value="Beginner"
)
st.markdown("---")
submit = st.form_submit_button("Save Profile", use_container_width=True)
if submit:
if not name:
st.error("Please enter your name.")
st.stop()
if not equipment:
st.error("Please select at least one equipment option.")
st.stop()
# Build prompt using the imported function
prompt, bmi, bmi_status = build_prompt(
name=name,
age=age,
gender=gender,
height=height,
weight=weight,
goal=goal,
fitness_level=fitness_level,
equipment=equipment
)
st.success("β
Profile Saved Successfully!")
st.session_state.update({
"form_submitted": True,
"name": name,
"bmi": bmi,
"bmi_status": bmi_status,
"age": age,
"goal": goal,
"equipment": equipment,
"fitness_level": fitness_level,
"height": height,
"weight": weight,
"gender": gender,
"prompt": prompt
})
# Show profile summary if form is submitted
if st.session_state.form_submitted:
st.markdown("---")
st.success(f"Welcome, **{st.session_state.name}**!")
col1, col2, col3 = st.columns(3)
col1.metric("π BMI", f"{st.session_state.bmi:.2f}")
col2.metric("π· Category", st.session_state.bmi_status)
col3.metric("ποΈ Level", st.session_state.fitness_level)
# Quick action button to switch to workout plan tab
if st.button("π Go to Workout Plan Tab", type="primary", use_container_width=True):
st.session_state.active_tab = "Workout Plan"
st.rerun()
# Profile Report Section
st.markdown("---")
with st.expander("π View Profile Report"):
report_text = f"""
FIT PLAN AI - PROFILE REPORT
Generated on: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
Name: {st.session_state.name}
Age: {st.session_state.age}
Gender: {st.session_state.gender}
Height: {st.session_state.height} cm
Weight: {st.session_state.weight} kg
BMI: {st.session_state.bmi:.2f}
Category: {st.session_state.bmi_status}
Goal: {st.session_state.goal}
Level: {st.session_state.fitness_level}
Equipment: {', '.join(st.session_state.equipment)}
Go to the Workout Plan tab to generate your personalized 5-day workout plan!
"""
st.download_button(
"π₯ Download Profile Report",
data=report_text,
file_name=f"FITPlanAI_{st.session_state.name}_Profile.txt",
mime="text/plain",
use_container_width=True
)
# Tab 2: Workout Plan
with tab2:
st.header("ποΈ Your Personalized Workout Plan")
# Check if profile is submitted
if not st.session_state.form_submitted:
st.warning("β οΈ Please set up your profile first in the 'Profile Setup' tab!")
if st.button("Go to Profile Setup"):
st.session_state.active_tab = "Profile"
st.rerun()
else:
# Check API status
if not st.session_state.get("api_status", False):
st.error("β οΈ API is not connected. Please check your HF_TOKEN environment variable or use local Ollama.")
st.stop()
# Show profile summary
with st.container():
st.markdown("### Profile Summary")
col1, col2, col3, col4 = st.columns(4)
col1.metric("Name", st.session_state.name)
col2.metric("Age", st.session_state.age)
col3.metric("BMI", f"{st.session_state.bmi:.1f}")
col4.metric("Goal", st.session_state.goal)
st.markdown("---")
# Generate Workout Plan Button
st.subheader("Generate Your 5-Day Workout Plan")
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
if st.button("π Generate Workout Plan", type="primary", use_container_width=True):
with st.spinner("Creating your personalized workout plan with Llama... This may take a moment."):
# Call the model API from model_api.py
workout_plan = query_model(st.session_state.prompt)
st.session_state.workout_plan = workout_plan
st.rerun()
# Display workout plan if generated
if st.session_state.workout_plan:
st.markdown("---")
st.subheader("π Your 5-Day Workout Plan")
# Check if plan is complete
is_complete, message = verify_workout_plan(st.session_state.workout_plan)
if not is_complete:
st.warning(f"β οΈ {message}. You can regenerate the plan if needed.")
# Display the workout plan in a nice container
with st.container():
st.markdown(st.session_state.workout_plan)
st.markdown("---")
# Action buttons
col1, col2, col3 = st.columns(3)
with col1:
# Download button for workout plan
workout_text = f"""
FIT PLAN AI - PERSONALIZED WORKOUT PLAN
Generated for: {st.session_state.name}
Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
Model: {selected_model}
PROFILE SUMMARY:
- Age: {st.session_state.age}
- BMI: {st.session_state.bmi:.2f} ({st.session_state.bmi_status})
- Goal: {st.session_state.goal}
- Level: {st.session_state.fitness_level}
- Equipment: {', '.join(st.session_state.equipment)}
{st.session_state.workout_plan}
---
Stay consistent and trust the process!
Generated by FIT Plan AI
"""
st.download_button(
"π₯ Download Plan",
data=workout_text,
file_name=f"FITPlanAI_{st.session_state.name}_Workout.txt",
mime="text/plain",
use_container_width=True
)
with col2:
if st.button("π Regenerate Plan", use_container_width=True):
with st.spinner("Regenerating your workout plan with Llama..."):
workout_plan = query_model(st.session_state.prompt)
st.session_state.workout_plan = workout_plan
st.rerun()
with col3:
if st.button("βοΈ Edit Profile", use_container_width=True):
st.session_state.active_tab = "Profile"
st.rerun()
# Tips section
with st.expander("π‘ Workout Tips & Guidelines"):
st.markdown("""
### π Tips for Best Results:
1. **Warm-up** before each workout (5-10 minutes of light cardio and dynamic stretches)
2. **Stay hydrated** during your workout
3. **Maintain proper form** over lifting heavy weights
4. **Rest adequately** between sets as specified
5. **Cool down** and stretch after each session
6. **Be consistent** - follow the plan regularly
7. **Listen to your body** and adjust intensity if needed
### β οΈ Safety First:
- Consult with a healthcare professional before starting any new exercise program
- Stop immediately if you feel sharp pain or discomfort
- Start with lighter weights to master the form
""")
# Footer
st.markdown("---")
st.caption("FIT Plan AI - Milestone 2 | Powered by Llama Models") |