DrishtiSharma commited on
Commit
17e349a
Β·
verified Β·
1 Parent(s): da8d0d4

Create w_debugging/app.py

Browse files
Files changed (1) hide show
  1. mylab/w_debugging/app.py +288 -0
mylab/w_debugging/app.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import matplotlib.pyplot as plt
3
+ import pandas as np
4
+ import tempfile
5
+ from datetime import datetime
6
+ from langchain_core.messages import HumanMessage
7
+ from tools import tools
8
+ from agents import *
9
+ from config import *
10
+ from workflow import create_workflow
11
+ import logging
12
+ import threading
13
+ import queue
14
+
15
+ # Global timeout variable
16
+ TIMEOUT_SECONDS = 300
17
+
18
+ # Initialize workflow
19
+ graph = create_workflow()
20
+
21
+ # Configure logging
22
+ logging.basicConfig(level=logging.DEBUG)
23
+ logger = logging.getLogger(__name__)
24
+
25
+ # Debug logs for displaying in UI
26
+ debug_logs = []
27
+
28
+ # Helper Functions
29
+ def run_graph(input_message, history, user_details):
30
+ def invoke_workflow(q):
31
+ try:
32
+ system_prompt = (
33
+ "You are a fitness and health assistant. "
34
+ "Provide actionable, tailored advice based on the user's personal details and goals. "
35
+ "Incorporate BMI and daily caloric needs into your suggestions. "
36
+ "Offer steps for achieving goals like weight loss or fitness improvement."
37
+ )
38
+
39
+ # Summarize user details
40
+ user_details_summary = (
41
+ f"Name: {user_details.get('name', 'Unknown')}, "
42
+ f"Age: {user_details.get('age', 'Unknown')}, "
43
+ f"Gender: {user_details.get('gender', 'Unknown')}, "
44
+ f"Weight: {user_details.get('weight', 'Unknown')} kg, "
45
+ f"Height: {user_details.get('height', 'Unknown')} cm, "
46
+ f"Activity Level: {user_details.get('activity_level', 'Unknown')}"
47
+ )
48
+
49
+ # Messages for the workflow
50
+ messages = [
51
+ {"role": "system", "content": system_prompt},
52
+ {"role": "user", "content": f"User details: {user_details_summary}"},
53
+ {"role": "user", "content": input_message}
54
+ ]
55
+
56
+ logger.debug("Invoking workflow with messages: %s", messages)
57
+ debug_logs.append(f"Workflow Input: {messages}")
58
+
59
+ response = graph.invoke({"messages": messages})
60
+ logger.debug("Workflow response: %s", response)
61
+ debug_logs.append(f"Workflow Response: {response}")
62
+
63
+ # Extract LLM response
64
+ llm_response = None
65
+ for msg in response.get("messages", []):
66
+ if isinstance(msg, HumanMessage) and msg.name in ["nutritionist", "workout_coach"]:
67
+ llm_response = msg.content
68
+ break
69
+
70
+ if llm_response:
71
+ q.put(llm_response)
72
+ else:
73
+ q.put("The workflow did not return a valid response. Please try again.")
74
+ except Exception as e:
75
+ logger.error("Error in run_graph: %s", str(e))
76
+ debug_logs.append(f"Error: {str(e)}")
77
+ q.put(f"An error occurred: {e}")
78
+
79
+ q = queue.Queue()
80
+ thread = threading.Thread(target=invoke_workflow, args=(q,))
81
+ thread.start()
82
+ thread.join(timeout=TIMEOUT_SECONDS)
83
+
84
+ if thread.is_alive():
85
+ logger.error(f"Workflow timed out after {TIMEOUT_SECONDS} seconds.")
86
+ debug_logs.append(f"Workflow timed out after {TIMEOUT_SECONDS} seconds.")
87
+ return f"The request took longer than {TIMEOUT_SECONDS} seconds and timed out. Please try again."
88
+ return q.get()
89
+
90
+
91
+ def calculate_bmi(height, weight):
92
+ height_m = height / 100
93
+ bmi = weight / (height_m ** 2)
94
+ if bmi < 18.5:
95
+ status = "underweight"
96
+ elif 18.5 <= bmi < 24.9:
97
+ status = "normal weight"
98
+ elif 25 <= bmi < 29.9:
99
+ status = "overweight"
100
+ else:
101
+ status = "obese"
102
+ return bmi, status
103
+
104
+
105
+ def visualize_bmi_and_calories(bmi, calories):
106
+ categories = ["Underweight", "Normal Weight", "Overweight", "Obese"]
107
+ bmi_values = [18.5, 24.9, 29.9, 40]
108
+ calorie_range = [1500, 2000, 2500, 3000]
109
+
110
+ fig, ax1 = plt.subplots(figsize=(10, 6))
111
+
112
+ # BMI Visualization
113
+ ax1.bar(categories, bmi_values, color=['blue', 'green', 'orange', 'red'], alpha=0.6, label="BMI Ranges")
114
+ ax1.axhline(y=bmi, color='purple', linestyle='--', linewidth=2, label=f"Your BMI: {bmi:.2f}")
115
+ ax1.set_ylabel("BMI Value")
116
+ ax1.set_title("BMI and Caloric Needs Visualization")
117
+ ax1.legend(loc="upper left")
118
+
119
+ # Calorie Visualization
120
+ ax2 = ax1.twinx()
121
+ ax2.plot(categories, calorie_range, 'o-', color='magenta', label="Calorie Ranges")
122
+ ax2.axhline(y=calories, color='cyan', linestyle='--', linewidth=2, label=f"Your Calorie Needs: {calories:.2f} kcal")
123
+ ax2.set_ylabel("Calories")
124
+ ax2.legend(loc="upper right")
125
+
126
+ plt.tight_layout()
127
+
128
+ # Save visualization to a temporary file
129
+ temp_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
130
+ try:
131
+ plt.savefig(temp_file.name)
132
+ finally:
133
+ plt.close()
134
+
135
+ return temp_file.name
136
+
137
+
138
+ def calculate_calories(age, weight, height, activity_level, gender):
139
+ if gender.lower() == "male":
140
+ bmr = 10 * weight + 6.25 * height - 5 * age + 5
141
+ else:
142
+ bmr = 10 * weight + 6.25 * height - 5 * age - 161
143
+
144
+ activity_multipliers = {
145
+ "sedentary": 1.2,
146
+ "lightly active": 1.375,
147
+ "moderately active": 1.55,
148
+ "very active": 1.725,
149
+ "extra active": 1.9,
150
+ }
151
+
152
+ activity_level = activity_level.lower()
153
+ return bmr * activity_multipliers.get(activity_level, 1.2)
154
+
155
+ # Interface Components
156
+ with gr.Blocks() as demo:
157
+ gr.Markdown("<strong>FIT.AI - Your Fitness and Wellbeing Coach</strong>")
158
+
159
+ debug_logs = []
160
+
161
+ with gr.Tabs():
162
+ with gr.Tab("Visualization + Chat"):
163
+ # User Input
164
+ with gr.Row():
165
+ user_name = gr.Textbox(placeholder="Enter your name", label="Name")
166
+ user_age = gr.Number(label="Age (years)", value=25, precision=0)
167
+ user_gender = gr.Dropdown(choices=["Male", "Female"], label="Gender", value="Male")
168
+ user_weight = gr.Number(label="Weight (kg)", value=70, precision=1)
169
+ user_height = gr.Number(label="Height (cm)", value=170, precision=1)
170
+ activity_level = gr.Dropdown(
171
+ choices=["Sedentary", "Lightly active", "Moderately active", "Very active", "Extra active"],
172
+ label="Activity Level",
173
+ value="Moderately active"
174
+ )
175
+
176
+ # Visualization Output
177
+ bmi_chart = gr.Image(label="BMI and Calorie Chart")
178
+ debug_output = gr.Textbox(label="Debug Logs", interactive=False, lines=10)
179
+
180
+ # Chat Outputs
181
+ with gr.Row():
182
+ chatbot = gr.Chatbot(label="Chat with FIT.AI")
183
+ text_input = gr.Textbox(placeholder="Type your question here...", label="Your Question")
184
+
185
+ submit_button = gr.Button("Submit")
186
+ clear_button = gr.Button("Clear Chat")
187
+
188
+ def submit_message(message, history=[]):
189
+ try:
190
+ # Debug logging
191
+ debug_logs.clear()
192
+ debug_logs.append("Processing user request...")
193
+
194
+ user_details = {
195
+ "name": user_name.value,
196
+ "age": user_age.value,
197
+ "weight": user_weight.value,
198
+ "height": user_height.value,
199
+ "activity_level": activity_level.value,
200
+ "gender": user_gender.value
201
+ }
202
+ debug_logs.append(f"User Details: {user_details}")
203
+
204
+ bmi, status = calculate_bmi(user_details['height'], user_details['weight'])
205
+ calories = calculate_calories(
206
+ user_details['age'], user_details['weight'], user_details['height'], user_details['activity_level'], user_details['gender']
207
+ )
208
+ chart_path = visualize_bmi_and_calories(bmi, calories)
209
+
210
+ user_prompt = (
211
+ f"User wants advice on: {message}\n"
212
+ f"User Details:\n"
213
+ f"- Name: {user_details['name']}\n"
214
+ f"- Age: {user_details['age']}\n"
215
+ f"- Gender: {user_details['gender']}\n"
216
+ f"- Weight: {user_details['weight']} kg\n"
217
+ f"- Height: {user_details['height']} cm\n"
218
+ f"- Activity Level: {user_details['activity_level']}\n"
219
+ f"- BMI: {bmi:.2f} ({status})\n"
220
+ f"- Daily Caloric Needs: {calories:.2f} kcal\n"
221
+ f"\nProvide tailored advice based on these metrics."
222
+ )
223
+ debug_logs.append(f"Composed user prompt: {user_prompt}")
224
+
225
+ response = run_graph(user_prompt, history, user_details)
226
+ debug_logs.append(f"Received response: {response}")
227
+
228
+ # Append the tailored response to the chatbot history
229
+ history.append(("User", message))
230
+ if isinstance(response, str):
231
+ history.append(("FIT.AI", response))
232
+ else:
233
+ history.append(("FIT.AI", "An unexpected response was received. Check debug logs for details."))
234
+
235
+ return history, chart_path, "\n".join(debug_logs)
236
+
237
+ except Exception as e:
238
+ error_message = f"Error: {str(e)}"
239
+ logger.error(error_message)
240
+ debug_logs.append(error_message)
241
+ return history + [("FIT.AI", "An error occurred. Please try again.")], None, "\n".join(debug_logs)
242
+
243
+ submit_button.click(submit_message, inputs=[text_input, chatbot], outputs=[chatbot, bmi_chart, debug_output])
244
+ clear_button.click(lambda: ([], "", ""), inputs=None, outputs=[chatbot, bmi_chart, debug_output])
245
+
246
+ # Calculator + Visualization Tab
247
+ with gr.Tab("Calculator + Visualization"):
248
+ user_age_calc = gr.Number(label="Age (years)", value=25, precision=0)
249
+ user_gender_calc = gr.Dropdown(choices=["Male", "Female"], label="Gender", value="Male")
250
+ user_weight_calc = gr.Number(label="Weight (kg)", value=70, precision=1)
251
+ user_height_calc = gr.Number(label="Height (cm)", value=170, precision=1)
252
+ activity_level_calc = gr.Dropdown(
253
+ choices=["Sedentary", "Lightly active", "Moderately active", "Very active", "Extra active"],
254
+ label="Activity Level",
255
+ value="Moderately active"
256
+ )
257
+
258
+ bmi_output = gr.Label(label="BMI Result")
259
+ calorie_output = gr.Label(label="Calorie Needs")
260
+ bmi_chart_calc = gr.Image(label="BMI and Calorie Chart")
261
+
262
+ calculate_button = gr.Button("Calculate")
263
+
264
+ def calculate_metrics(age, weight, height, gender, activity_level):
265
+ try:
266
+ debug_logs.clear()
267
+ debug_logs.append("Processing calculator request...")
268
+
269
+ bmi, status = calculate_bmi(height, weight)
270
+ calories = calculate_calories(age, weight, height, activity_level, gender)
271
+ chart_path = visualize_bmi_and_calories(bmi, calories)
272
+
273
+ debug_logs.append(f"Calculated metrics: BMI={bmi:.2f}, Calories={calories:.2f}")
274
+ return f"Your BMI is {bmi:.2f}, considered {status}.", f"Daily calorie needs: {calories:.2f} kcal", chart_path
275
+
276
+ except Exception as e:
277
+ error_message = f"Error: {str(e)}"
278
+ logger.error(error_message)
279
+ debug_logs.append(error_message)
280
+ return "An error occurred.", "", None
281
+
282
+ calculate_button.click(
283
+ calculate_metrics,
284
+ inputs=[user_age_calc, user_weight_calc, user_height_calc, user_gender_calc, activity_level_calc],
285
+ outputs=[bmi_output, calorie_output, bmi_chart_calc]
286
+ )
287
+
288
+ demo.launch(share=True)