-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhealth_agent.py
244 lines (210 loc) Β· 10.1 KB
/
health_agent.py
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
import streamlit as st
from phi.agent import Agent
from phi.model.google import Gemini
st.set_page_config(
page_title="AI Health & Fitness Planner",
page_icon="ποΈββοΈ",
layout="wide",
initial_sidebar_state="expanded"
)
st.markdown("""
<style>
.main {
padding: 2rem;
}
.stButton>button {
width: 100%;
border-radius: 5px;
height: 3em;
}
.success-box {
padding: 1rem;
border-radius: 0.5rem;
background-color: #f0fff4;
border: 1px solid #9ae6b4;
}
.warning-box {
padding: 1rem;
border-radius: 0.5rem;
background-color: #fffaf0;
border: 1px solid #fbd38d;
}
div[data-testid="stExpander"] div[role="button"] p {
font-size: 1.1rem;
font-weight: 600;
}
</style>
""", unsafe_allow_html=True)
def display_dietary_plan(plan_content):
with st.expander("π Your Personalized Dietary Plan", expanded=True):
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("### π― Why this plan works")
st.info(plan_content.get("why_this_plan_works", "Information not available"))
st.markdown("### π½οΈ Meal Plan")
st.write(plan_content.get("meal_plan", "Plan not available"))
with col2:
st.markdown("### β οΈ Important Considerations")
considerations = plan_content.get("important_considerations", "").split('\n')
for consideration in considerations:
if consideration.strip():
st.warning(consideration)
def display_fitness_plan(plan_content):
with st.expander("πͺ Your Personalized Fitness Plan", expanded=True):
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("### π― Goals")
st.success(plan_content.get("goals", "Goals not specified"))
st.markdown("### ποΈββοΈ Exercise Routine")
st.write(plan_content.get("routine", "Routine not available"))
with col2:
st.markdown("### π‘ Pro Tips")
tips = plan_content.get("tips", "").split('\n')
for tip in tips:
if tip.strip():
st.info(tip)
def main():
if 'dietary_plan' not in st.session_state:
st.session_state.dietary_plan = {}
st.session_state.fitness_plan = {}
st.session_state.qa_pairs = []
st.session_state.plans_generated = False
st.title("ποΈββοΈ AI Health & Fitness Planner")
st.markdown("""
<div style='background-color: #FFFFFFF; padding: 1rem; border-radius: 0.5rem; margin-bottom: 2rem;'>
Get personalized dietary and fitness plans tailored to your goals and preferences.
Our AI-powered system considers your unique profile to create the perfect plan for you.
</div>
""", unsafe_allow_html=True)
with st.sidebar:
st.header("π API Configuration")
gemini_api_key = st.text_input(
"Gemini API Key",
type="password",
help="Enter your Gemini API key to access the service"
)
if not gemini_api_key:
st.warning("β οΈ Please enter your Gemini API Key to proceed")
st.markdown("[Get your API key here](https://aistudio.google.com/apikey)")
return
st.success("API Key accepted!")
if gemini_api_key:
try:
gemini_model = Gemini(id="gemini-1.5-flash", api_key=gemini_api_key)
except Exception as e:
st.error(f"β Error initializing Gemini model: {e}")
return
st.header("π€ Your Profile")
col1, col2 = st.columns(2)
with col1:
age = st.number_input("Age", min_value=10, max_value=100, step=1, help="Enter your age")
height = st.number_input("Height (in)", min_value=60.0, max_value=80.0, step=0.1)
activity_level = st.selectbox(
"Activity Level",
options=["Sedentary", "Lightly Active", "Moderately Active", "Very Active", "Extremely Active"],
help="Choose your typical activity level"
)
dietary_preferences = st.selectbox(
"Dietary Preferences",
options=["Vegetarian", "Keto", "Gluten Free", "Low Carb", "Dairy Free"],
help="Select your dietary preference"
)
with col2:
weight = st.number_input("Weight (lb)", min_value=100.0, max_value=300.0, step=1.0)
sex = st.selectbox("Sex", options=["Male", "Female", "Other"])
fitness_goals = st.selectbox(
"Fitness Goals",
options=["Lose Weight", "Gain Muscle", "Endurance", "Stay Fit", "Strength Training"],
help="What do you want to achieve?"
)
if st.button("π― Generate My Personalized Plan", use_container_width=True):
with st.spinner("Creating your perfect health and fitness routine..."):
try:
dietary_agent = Agent(
name="Dietary Expert",
role="Provides personalized dietary recommendations",
model=gemini_model,
instructions=[
"Consider the user's input, including dietary restrictions and preferences.",
"Suggest a detailed meal plan for the day, including breakfast, lunch, dinner, and snacks.",
"Provide a brief explanation of why the plan is suited to the user's goals.",
"Focus on clarity, coherence, and quality of the recommendations.",
]
)
fitness_agent = Agent(
name="Fitness Expert",
role="Provides personalized fitness recommendations",
model=gemini_model,
instructions=[
"Provide exercises tailored to the user's goals.",
"Include warm-up, main workout, and cool-down exercises.",
"Explain the benefits of each recommended exercise.",
"Ensure the plan is actionable and detailed.",
]
)
user_profile = f"""
Age: {age}
Weight: {weight}lb
Height: {height}in
Sex: {sex}
Activity Level: {activity_level}
Dietary Preferences: {dietary_preferences}
Fitness Goals: {fitness_goals}
"""
dietary_plan_response = dietary_agent.run(user_profile)
dietary_plan = {
"why_this_plan_works": "High Protein, Healthy Fats, Moderate Carbohydrates, and Caloric Balance",
"meal_plan": dietary_plan_response.content,
"important_considerations": """
- Hydration: Drink plenty of water throughout the day
- Electrolytes: Monitor sodium, potassium, and magnesium levels
- Fiber: Ensure adequate intake through vegetables and fruits
- Listen to your body: Adjust portion sizes as needed
"""
}
fitness_plan_response = fitness_agent.run(user_profile)
fitness_plan = {
"goals": "Build strength, improve endurance, and maintain overall fitness",
"routine": fitness_plan_response.content,
"tips": """
- Track your progress regularly
- Allow proper rest between workouts
- Focus on proper form
- Stay consistent with your routine
"""
}
st.session_state.dietary_plan = dietary_plan
st.session_state.fitness_plan = fitness_plan
st.session_state.plans_generated = True
st.session_state.qa_pairs = []
display_dietary_plan(dietary_plan)
display_fitness_plan(fitness_plan)
except Exception as e:
st.error(f"β An error occurred: {e}")
if st.session_state.plans_generated:
st.header("β Questions about your plan?")
question_input = st.text_input("What would you like to know?")
if st.button("Get Answer"):
if question_input:
with st.spinner("Finding the best answer for you..."):
dietary_plan = st.session_state.dietary_plan
fitness_plan = st.session_state.fitness_plan
context = f"Dietary Plan: {dietary_plan.get('meal_plan', '')}\n\nFitness Plan: {fitness_plan.get('routine', '')}"
full_context = f"{context}\nUser Question: {question_input}"
try:
agent = Agent(model=gemini_model, show_tool_calls=True, markdown=True)
run_response = agent.run(full_context)
if hasattr(run_response, 'content'):
answer = run_response.content
else:
answer = "Sorry, I couldn't generate a response at this time."
st.session_state.qa_pairs.append((question_input, answer))
except Exception as e:
st.error(f"β An error occurred while getting the answer: {e}")
if st.session_state.qa_pairs:
st.header("π¬ Q&A History")
for question, answer in st.session_state.qa_pairs:
st.markdown(f"**Q:** {question}")
st.markdown(f"**A:** {answer}")
if __name__ == "__main__":
main()