import os import gradio as gr import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots from langchain_groq import ChatGroq from langchain.prompts import PromptTemplate from typing import TypedDict, List from typing_extensions import Annotated from dotenv import load_dotenv import numpy as np load_dotenv() api_key = os.getenv('GROQ_API_KEY') class AssessmentOutput(TypedDict): stress_management: Annotated[float, "Percentage score (0-100) for Stress Management KPI"] motivation: Annotated[float, "Percentage score (0-100) for Motivation KPI"] restless_night_score: Annotated[float, "Percentage score (0-100) for Restless Night Score KPI"] anxiety_level: Annotated[float, "Percentage score (0-100) for Anxiety Level KPI"] burnout_level: Annotated[float, "Percentage score (0-100) for Burnout Level KPI"] physical_fitness_score: Annotated[float, "Percentage score (0-100) for Physical Fitness KPI"] dietary_habit_score: Annotated[float, "Percentage score (0-100) for Diet & Nutrition KPI"] focus_score: Annotated[float, "Percentage score (0-100) for Cognitive Performance and Focus KPI"] overall_wellness_score: Annotated[float, "Percentage score (0-100) based on all the individual KPIs"] package: Annotated[List[str], "List of recommended packages. Options include 'Focus', 'Fitness', and 'Insomnia'. The recommendation can be a single package, a combination of packages, or all three packages based on the assessment."] report: Annotated[str, "A detailed summary report of the assessment results and recommendations based on the KPI analysis."] template = """ You are an AI wellness assessment system designed to evaluate users' well-being and provide personalized insights. This assessment system analyzes responses and generates wellness reports, recommending specific services and packages from *DailyWellnessAI* to help users improve their mental and physical health. While this system itself is not called *DailyWellnessAI*, all recommendations are part of the *DailyWellnessAI* platform. Based on the user's responses to the following 15 questions, along with their personal details (Age, Gender, Height, Weight), predict the following KPIs as percentages out of 100: - stress_management - motivation - restless_night_score - anxiety_level - burnout_level - physical_fitness_score - dietary_habit_score - focus_score - overall_wellness_score **Recommendation System:** Based on the predicted KPIs, recommend one of the following *DailyWellnessAI* packages: - Focus (for low concentration, motivation, burnout, mental fog, and lack of focus) - Insomnia (for sleep disturbances, restlessness, anxiety before sleep, difficulty sleeping, and poor sleep quality) - Fitness (for low physical activity, poor dietary habits, weak physical strength, low endurance, and lack of energy) If the overall_wellness_score is greater than 90 (or 95), recommend all three packages and let the user choose among them, emphasizing that DailyWellnessAI offers holistic well-being solutions. **Summary Report:** Provide a brief wellness summary explaining the predicted KPIs and recommended package(s) based on the user's responses. Justify the recommendations by highlighting key factors affecting the user's well-being and how DailyWellnessAI can help improve them. Take into account the user's name, age, gender, height, and weight when providing recommendations. ### Personal Details: - Age: {age} - Gender: {gender} - Height: {height} - Weight: {weight} ### Assessment Questions: 1. How often do you feel stressed by daily tasks? Options: Never, Sometimes, Often, Always Answer: {ans1} 2. How well do you handle stress? Options: Excellent, Good, Fair, Poor Answer: {ans2} 3. How would you rate your current level of burnout? Options: None, Mild, Moderate, Severe Answer: {ans3} 4. How well can you concentrate on your daily tasks? Options: Excellent, Good, Fair, Poor Answer: {ans4} 5. How often do you have trouble falling asleep? Options: Never, Rarely, Sometimes, Always Answer: {ans5} 6. How would you rate the quality of your sleep? Options: Excellent, Good, Fair, Poor Answer: {ans6} 7. How often do you wake up during the night? Options: Never, Rarely, Sometimes, Often Answer: {ans7} 8. How often do you feel anxious before sleep? Options: Never, Rarely, Sometimes, Often Answer: {ans8} 9. How happy are you with your eating habits? Options: Very happy, Happy, Unhappy, Very unhappy Answer: {ans9} 10. How balanced is your diet? Options: Very balanced, Balanced, Unbalanced, Very unbalanced Answer: {ans10} 11. How often do you exercise or do physical activity? Options: Daily, Several times a week, Once a week, Never Answer: {ans11} 12. How would you rate your physical strength? Options: Excellent, Good, Fair, Poor Answer: {ans12} 13. How motivated are you to work on your wellness goals daily? Options: Very motivated, Moderately motivated, Slightly motivated, Not at all Answer: {ans13} 14. How would you rate your overall health and well-being? Options: Excellent, Good, Fair, Poor Answer: {ans14} 15. Any more remarks about yourself that you want to add? Answer: {ans15} Use the responses and personal details to generate KPI predictions, determine the recommended *DailyWellnessAI* package(s), and provide a concise summary report that briefly justifies the recommendations, taking into account the user's age, gender, height, and weight. """ chat = ChatGroq(api_key=api_key, model="llama-3.3-70b-versatile", temperature=0.2) prompt_template = PromptTemplate( input_variables=["age", "gender", "height", "weight"] + [f"ans{i}" for i in range(1, 16)], template=template ) def run_assessment(personal_details, answers): prompt = prompt_template.format(**personal_details, **answers) structured_llm = chat.with_structured_output(AssessmentOutput) return structured_llm.invoke(prompt) def get_emoji(score): if score < 20: return "😢" elif score < 40: return "😞" elif score < 60: return "😐" elif score < 80: return "🙂" else: return "😄" def create_overall_wellness_donut(score): color = '#FF5252' if score < 50 else '#FFC107' if score < 75 else '#4CAF50' fig = go.Figure(go.Pie( values=[score, 100 - score], hole=0.7, textinfo='none', marker_colors=[color, '#E0E0E0'], showlegend=False )) fig.update_layout( annotations=[dict( text=f"{get_emoji(score)}", font_size=24, showarrow=False )], title=dict(text="Overall Wellness", x=0.5, font=dict(size=16)), margin=dict(t=20, b=20, l=20, r=20), height=300 ) return fig def create_kpi_bar_chart(kpis, values): colors = ['#FF5252' if v < 50 else '#FFC107' if v < 75 else '#4CAF50' for v in values] fig = go.Figure(go.Bar( x=kpis, y=values, marker_color=colors, text=[f"{v}%" for v in values], textposition='auto' )) fig.update_layout( title="KPI Breakdown", xaxis=dict(title="KPI"), yaxis=dict(title="Score (%)", range=[0, 100]), margin=dict(l=40, r=40, t=60, b=40), height=400 ) return fig def create_radar_chart(data): categories = [ 'Stress Management', 'Motivation', 'Sleep Quality', 'Anxiety Control', 'Burnout Resistance', 'Physical Fitness', 'Diet & Nutrition', 'Focus' ] values = [ float(data['stress_management']), float(data['motivation']), 100 - float(data['restless_night_score']), 100 - float(data['anxiety_level']), 100 - float(data['burnout_level']), float(data['physical_fitness_score']), float(data['dietary_habit_score']), float(data['focus_score']) ] fig = go.Figure() fig.add_trace(go.Scatterpolar( r=values, theta=categories, fill='toself', fillcolor='rgba(76, 175, 80, 0.3)', line=dict(color='#4CAF50', width=2), name='Your Profile' )) fig.update_layout( polar=dict( radialaxis=dict(visible=True, range=[0, 100], tickfont=dict(size=10)) ), showlegend=False, margin=dict(l=40, r=40, t=20, b=20), height=400 ) return fig def create_bullet_charts_combined(data): bullet_data = [ ("Stress Management", float(data['stress_management'])), ("Motivation", float(data['motivation'])), ("Sleep Quality", 100 - float(data['restless_night_score'])), ("Anxiety Control", 100 - float(data['anxiety_level'])), ("Burnout Resistance", 100 - float(data['burnout_level'])), ("Physical Fitness", float(data['physical_fitness_score'])), ("Diet & Nutrition", float(data['dietary_habit_score'])), ("Focus", float(data['focus_score'])) ] rows, cols = 2, 4 target = 80 fig = make_subplots(rows=rows, cols=cols, subplot_titles=[item[0] for item in bullet_data]) for i, (label, val) in enumerate(bullet_data): row = i // cols + 1 col = i % cols + 1 fig.add_trace(go.Bar( x=[val], y=[""], orientation="h", marker_color='#4CAF50' if val >= target else '#FF5252', text=[f"{val}%"], textposition='inside', showlegend=False ), row=row, col=col) fig.update_xaxes(range=[0, 100], row=row, col=col) fig.add_shape( type="line", x0=target, x1=target, y0=0, y1=1, xref=f"x{i+1}", yref=f"y{i+1}", line=dict(color="black", width=2, dash="dash") ) fig.update_layout(height=400, width=1000, margin=dict(l=20, r=20, t=40, b=20)) return fig def combine_report(results): packages = results["package"] rec_text = ", ".join(packages) if packages else "None" final_text = f"### Report\n{results['report']}\n\n**Recommended Packages:** {rec_text}" return final_text def gradio_assessment( age, gender, height, weight, ans1, ans2, ans3, ans4, ans5, ans6, ans7, ans8, ans9, ans10, ans11, ans12, ans13, ans14, ans15 ): personal_details = { "age": age, "gender": gender, "height": height, "weight": weight } answers = { "ans1": ans1, "ans2": ans2, "ans3": ans3, "ans4": ans4, "ans5": ans5, "ans6": ans6, "ans7": ans7, "ans8": ans8, "ans9": ans9, "ans10": ans10, "ans11": ans11, "ans12": ans12, "ans13": ans13, "ans14": ans14, "ans15": ans15 } results = run_assessment(personal_details, answers) overall_score = int(float(results["overall_wellness_score"])) donut_fig = create_overall_wellness_donut(overall_score) kpis = [ "Stress Management", "Motivation", "Sleep Quality", "Anxiety Control", "Burnout Resistance", "Physical Fitness", "Diet & Nutrition", "Focus" ] values = [ float(results["stress_management"]), float(results["motivation"]), 100 - float(results["restless_night_score"]), 100 - float(results["anxiety_level"]), 100 - float(results["burnout_level"]), float(results["physical_fitness_score"]), float(results["dietary_habit_score"]), float(results["focus_score"]) ] bar_fig = create_kpi_bar_chart(kpis, values) radar_fig = create_radar_chart(results) bullet_fig = create_bullet_charts_combined(results) report_text = combine_report(results) return donut_fig, bar_fig, radar_fig, bullet_fig, report_text def build_app(): with gr.Blocks() as demo: gr.Markdown("# 🌿 DailyWellnessAI Assessment") gr.Markdown("Fill out the questionnaire below to receive personalized insights and recommendations.") with gr.Row(): with gr.Column(): age = gr.Number(label="Your Age") gender = gr.Dropdown(label="Your Gender", choices=["Male", "Female", "Other"], value="Male") height = gr.Textbox(label="Your Height (e.g., 180 cm)", placeholder="Enter your height") weight = gr.Textbox(label="Your Weight (e.g., 80 kg)", placeholder="Enter your weight") with gr.Column(): ans1 = gr.Dropdown(label="1. How often do you feel stressed by daily tasks?", choices=["Never", "Sometimes", "Often", "Always"], value="Never") ans2 = gr.Dropdown(label="2. How well do you handle stress?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good") ans3 = gr.Dropdown(label="3. How would you rate your current level of burnout?", choices=["None", "Mild", "Moderate", "Severe"], value="None") ans4 = gr.Dropdown(label="4. How well can you concentrate on your daily tasks?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good") ans5 = gr.Dropdown(label="5. How often do you have trouble falling asleep?", choices=["Never", "Rarely", "Sometimes", "Always"], value="Rarely") ans6 = gr.Dropdown(label="6. How would you rate the quality of your sleep?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good") ans7 = gr.Dropdown(label="7. How often do you wake up during the night?", choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely") ans8 = gr.Dropdown(label="8. How often do you feel anxious before sleep?", choices=["Never", "Rarely", "Sometimes", "Often"], value="Rarely") with gr.Column(): ans9 = gr.Dropdown(label="9. How happy are you with your eating habits?", choices=["Very happy", "Happy", "Unhappy", "Very unhappy"], value="Happy") ans10 = gr.Dropdown(label="10. How balanced is your diet?", choices=["Very balanced", "Balanced", "Unbalanced", "Very unbalanced"], value="Balanced") ans11 = gr.Dropdown(label="11. How often do you exercise or do physical activity?", choices=["Daily", "Several times a week", "Once a week", "Never"], value="Daily") ans12 = gr.Dropdown(label="12. How would you rate your physical strength?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good") ans13 = gr.Dropdown(label="13. How motivated are you to work on your wellness goals daily?", choices=["Very motivated", "Moderately motivated", "Slightly motivated", "Not at all"], value="Very motivated") ans14 = gr.Dropdown(label="14. How would you rate your overall health and well-being?", choices=["Excellent", "Good", "Fair", "Poor"], value="Good") ans15 = gr.Textbox(label="15. Any more remarks about yourself that you want to add?", lines=3) with gr.Row(): submit_btn = gr.Button("Submit Assessment") with gr.Row(): gr.Markdown("## Results") with gr.Row(): donut_plot = gr.Plot(label="Overall Wellness Donut") bar_plot = gr.Plot(label="KPI Bar Chart") with gr.Row(): radar_plot = gr.Plot(label="Radar Chart") bullet_plot = gr.Plot(label="Bullet Charts") with gr.Row(): report_md = gr.Markdown(label="Assessment Report") submit_btn.click( fn=gradio_assessment, inputs=[age, gender, height, weight, ans1, ans2, ans3, ans4, ans5, ans6, ans7, ans8, ans9, ans10, ans11, ans12, ans13, ans14, ans15], outputs=[donut_plot, bar_plot, radar_plot, bullet_plot, report_md] ) return demo if __name__ == "__main__": demo_app = build_app() demo_app.launch(server_name="0.0.0.0", server_port=7860, share=True)