File size: 7,063 Bytes
f5759ff
eefbdd1
 
1e87777
eefbdd1
 
 
 
 
 
 
 
 
 
 
 
 
4395a28
6d02a71
1e87777
 
 
 
 
 
ca4603b
 
eefbdd1
 
 
 
ca4603b
eefbdd1
 
1e87777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eefbdd1
 
1e87777
 
eefbdd1
 
 
 
 
1e87777
 
ca4603b
 
 
 
 
 
 
 
 
 
eefbdd1
1e87777
 
 
 
eefbdd1
 
1e87777
 
ca4603b
 
 
 
 
 
 
 
1e87777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# chain_problems.py
import json
import logging
from typing import Dict, Optional
from langchain import PromptTemplate, LLMChain
from models import chat_model

logger = logging.getLogger(__name__)

problem_prompt_template = PromptTemplate(
    input_variables=["responses", "internal_report"],
    template=(
        "You are a wellness analyst. You have the following user responses to health-related questions:\n"
        "{responses}\n\n"
        "You also have an internal analysis report:\n"
        "{internal_report}\n\n"
        "From these inputs, determine a 'problem severity percentage' for the user in the following areas: "
        "stress_management, low_therapy, balanced_weight, restless_night, lack_of_motivation, gut_health, anxiety, burnout.\n\n"
        "Consider how these severity percentages will later be used to recommend suitable wellness packages such as:\n\n"
        "1. Fitness Mobility\n"
        "2. Balance Weight\n"
        "3. No More Insomnia\n"
        "4. Chronic Care\n"
        "5. Mental Wellness\n"
        "6. Focus Flow\n\n"
        "Return your answer in JSON format with keys: stress_management, low_therapy, balanced_weight, restless_night, "
        "lack_of_motivation, gut_health, anxiety, burnout.\n"
        "Ensure severity percentages are numbers from 0 to 100.\n\n"
        "JSON Output:"
    )
)

problem_chain = LLMChain(llm=chat_model, prompt=problem_prompt_template)


def recommend_wellness_packages(
    problems: Dict[str, float],
    sleep_hours: Optional[float] = None
) -> Dict[str, str]:
    """
    Given the severity dictionary and the user's reported sleep hours,
    recommend one or more wellness packages. 

    Returns:
        A dictionary with:
          - 'recommended_packages': comma-separated string of package names
          - 'recommendation_details': textual explanation of why these were chosen
    """
    # Threshold for considering an issue "significant"
    THRESHOLD = 50.0
    
    recommended = []
    rationale = []

    # 1. Stress / Mood => "Mental Wellness", "Focus Flow"
    if (
        problems["stress_management"] >= THRESHOLD 
        or problems["anxiety"] >= THRESHOLD 
        or problems["burnout"] >= THRESHOLD
        or problems["low_therapy"] >= THRESHOLD
        or problems["lack_of_motivation"] >= THRESHOLD
    ):
        recommended.append("Mental Wellness")
        rationale.append(
            "Mental Wellness Package suggested due to elevated stress, anxiety, "
            "or motivation-related concerns."
        )
    
    if problems["lack_of_motivation"] >= THRESHOLD or problems["stress_management"] >= THRESHOLD:
        recommended.append("Focus Flow")
        rationale.append(
            "Focus Flow Package recommended to improve concentration and reduce mental fatigue."
        )

    # 2. Balanced Weight / Gut Health => "Balance Weight"
    if problems["balanced_weight"] >= THRESHOLD or problems["gut_health"] >= THRESHOLD:
        recommended.append("Balance Weight")
        rationale.append(
            "Balance Weight Package suggested due to weight management or gut health concerns."
        )

    # 3. Restless nights => "No More Insomnia"
    #    **FIX**: Only recommend if user sleeps < 4 hours (to avoid recommending it for 10+ hours).
    if sleep_hours is not None and sleep_hours < 4:
        # If the user is sleeping less than 4 hours, we consider insomnia a big issue.
        recommended.append("No More Insomnia")
        rationale.append(
            "No More Insomnia Package recommended because the user reported sleeping less than 4 hours."
        )

    # 4. High burnout => "Chronic Care"
    if problems["burnout"] >= THRESHOLD:
        recommended.append("Chronic Care")
        rationale.append(
            "Chronic Care Package recommended to help manage long-term stress and burnout."
        )

    # 5. If user has borderline or higher weight/stress => "Fitness Mobility"
    if (
        problems["balanced_weight"] >= (THRESHOLD * 0.7) 
        or problems["stress_management"] >= (THRESHOLD * 0.7)
    ):
        recommended.append("Fitness Mobility")
        rationale.append(
            "Fitness Mobility Package may support better physical conditioning and relieve stress."
        )

    # Ensure uniqueness if appended multiple times
    unique_packages = list(dict.fromkeys(recommended))

    # Build a clear explanation
    recommendation_details = "\n".join(rationale) if rationale else "No particular issues detected."

    return {
        "recommended_packages": ", ".join(unique_packages),
        "recommendation_details": recommendation_details
    }


def analyze_problems_with_chain(responses: Dict[str, str], internal_report: str) -> Dict[str, object]:
    """
    Analyzes user responses and internal report to extract problem severity
    and then recommends relevant wellness packages.
    
    Returns:
        A dictionary with:
          - keys for each problem severity (stress_management, low_therapy, etc.)
          - 'recommended_packages': comma-separated package names
          - 'recommendation_details': textual explanation
    """
    responses_str = "\n".join(f"{q}: {a}" for q, a in responses.items())
    raw_text = problem_chain.run(responses=responses_str, internal_report=internal_report)
    
    # Try to parse problem severities from LLM output
    try:
        start_idx = raw_text.find('{')
        end_idx = raw_text.rfind('}') + 1
        json_str = raw_text[start_idx:end_idx]
        problems = json.loads(json_str)

        # Ensure all eight keys exist
        for key in [
            "stress_management",
            "low_therapy",
            "balanced_weight",
            "restless_night",
            "lack_of_motivation",
            "gut_health",
            "anxiety",
            "burnout"
        ]:
            problems.setdefault(key, 0.0)

        # Convert values to float
        problems = {k: float(v) for k, v in problems.items()}

    except Exception as e:
        logger.error(f"Error parsing problem percentages from LLM: {e}")
        # Default to zero severities
        problems = {
            "stress_management": 0.0,
            "low_therapy": 0.0,
            "balanced_weight": 0.0,
            "restless_night": 0.0,
            "lack_of_motivation": 0.0,
            "gut_health": 0.0,
            "anxiety": 0.0,
            "burnout": 0.0
        }

    # --- EXTRACT USER SLEEP HOURS ---
    # We assume the user answer is in responses["sleep_duration"] or similar key.
    # If your data uses a different key for the hours of sleep, adjust accordingly.
    sleep_hours = None
    if "sleep_duration" in responses:
        try:
            sleep_hours = float(responses["sleep_duration"])
        except ValueError:
            sleep_hours = None

    # Now get the recommendations based on problem severities + sleep_hours
    recommendations = recommend_wellness_packages(problems, sleep_hours=sleep_hours)

    # Merge and return
    return {
        **problems,
        **recommendations
    }