Spaces:
Sleeping
Sleeping
# 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 | |
} | |