DocUA commited on
Commit
3abb514
·
0 Parent(s):

Initial commit: Lifestyle clinical application with Gradio interface

Browse files

- Add main application files (app.py, app_config.py)
- Include system architecture diagrams and documentation
- Add lifestyle profile and clinical background data
- Setup requirements and configuration files

.gitignore ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+ .env.development.local
5
+ .env.test.local
6
+ .env.production.local
7
+
8
+ # Python
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+ *.so
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ pip-wheel-metadata/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+
33
+ # Virtual environments
34
+ venv/
35
+ env/
36
+ ENV/
37
+ env.bak/
38
+ venv.bak/
39
+
40
+ # IDEs
41
+ .vscode/
42
+ .idea/
43
+ *.swp
44
+ *.swo
45
+ *~
46
+
47
+ # OS
48
+ .DS_Store
49
+ .DS_Store?
50
+ ._*
51
+ .Spotlight-V100
52
+ .Trashes
53
+ ehthumbs.db
54
+ Thumbs.db
55
+
56
+ # Gradio
57
+ gradio_cached_examples/
58
+ flagged/
59
+
60
+ # Logs
61
+ *.log
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
3
+ TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
4
+ cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
5
+ WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
6
+ ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
7
+ MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
8
+ h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
9
+ 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
10
+ A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
11
+ T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
12
+ B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
13
+ B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
14
+ KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
15
+ OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
16
+ jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
17
+ qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
18
+ rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
19
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
20
+ hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
21
+ ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
22
+ 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
23
+ NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
24
+ ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
25
+ TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
26
+ jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
27
+ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
28
+ 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
29
+ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
30
+ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
31
+ -----END CERTIFICATE-----
README.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Lifestyle Journey MVP
3
+ emoji: 🏥
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 4.0.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # 🏥 Lifestyle Journey MVP
14
+
15
+ Тестовий чат-бот з медичним асистентом та lifestyle коучингом на базі Gemini API.
16
+
17
+ ## ⚡ Швидкий старт
18
+
19
+ 1. **Налаштуйте API ключ** в розділі Settings → Variables and secrets
20
+ - Додайте змінну `GEMINI_API_KEY` з вашим Gemini API ключем
21
+
22
+ 2. **Почніть тестування:**
23
+ - Медичні питання: "У мене болить груди"
24
+ - Lifestyle: "Хочу почати займатися спортом"
25
+
26
+ ## 🎯 Функціонал
27
+
28
+ ### Session Controller
29
+ - **Автоматичне визначення режиму** (medical/lifestyle)
30
+ - **Red flags детекція** для ургентних станів
31
+ - **JSON-based рішення** для прозорості логіки
32
+
33
+ ### Medical Assistant
34
+ - Медичні консультації з урахуванням хронічних станів
35
+ - Безпечні рекомендації та тріаж
36
+ - Направлення до лікарів при необхідності
37
+
38
+ ### Lifestyle Coach
39
+ - Персоналізовані поради по фізактивності
40
+ - Рекомендації з харчування
41
+ - Прогресія з урахуванням медичних обмежень
42
+ - Автоматичне оновлення профілю пацієнта
43
+
44
+ ## 🧪 Тестові сценарії
45
+
46
+ ```
47
+ 🚨 Медичні ургентні стани:
48
+ - "У мене сильний біль у грудях"
49
+ - "Тиск 190/110, що робити?"
50
+ - "Втрачаю свідомість"
51
+
52
+ 💚 Lifestyle коучинг:
53
+ - "Хочу схуднути безпечно"
54
+ - "Які вправи можна при діабеті?"
55
+ - "Допоможіть скласти план харчування"
56
+
57
+ 🔄 Змішані запити:
58
+ - "Чи можна бігати з гіпертонією?"
59
+ - "Болить спина після тренувань"
60
+ ```
61
+
62
+ ## 📊 Архітектура
63
+
64
+ ```mermaid
65
+ graph TD
66
+ A[Повідомлення пацієнта] --> B[Session Controller]
67
+ B --> C{JSON рішення}
68
+ C -->|medical| D[Medical Assistant]
69
+ C -->|lifestyle| E[Lifestyle Assistant]
70
+ D --> F[Відповідь + Clinical Context]
71
+ E --> G[Відповідь + Updated Profile]
72
+ ```
73
+
74
+ ## ⚠️ Важлива інформація
75
+
76
+ - **Тільки для тестування** - не замінює медичну допомогу
77
+ - При серйозних симптомах - звертайтесь до лікаря
78
+ - API ключ зберігається безпечно в HuggingFace Spaces
79
+
80
+ ## 🔧 Для розробників
81
+
82
+ Якщо хочете запустити локально:
83
+
84
+ ```bash
85
+ git clone <this-repo>
86
+ pip install -r requirements.txt
87
+ cp .env.example .env
88
+ # Додайте ваш GEMINI_API_KEY в .env
89
+ python app.py
90
+ ```
91
+
92
+ ---
93
+
94
+ Made with ❤️ for healthcare innovation
README_local.md ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🏥 Lifestyle Journey MVP
2
+
3
+ Тестовий чат-бот з медичним асистентом та lifestyle коучингом на базі Gemini API.
4
+
5
+ ## 🚀 Локальний запуск
6
+
7
+ ### 1. Встановлення залежностей
8
+ ```bash
9
+ pip install -r requirements.txt
10
+ ```
11
+
12
+ ### 2. Налаштування API ключа
13
+ 1. Скопіюйте `.env.example` в `.env`:
14
+ ```bash
15
+ cp .env.example .env
16
+ ```
17
+
18
+ 2. Відредагуйте `.env` файл та додайте ваш Gemini API ключ:
19
+ ```
20
+ GEMINI_API_KEY=your_actual_api_key_here
21
+ ```
22
+
23
+ ### 3. Запуск
24
+ ```bash
25
+ python app.py
26
+ ```
27
+
28
+ Застосунок запуститься на `http://localhost:7860`
29
+
30
+ ## 🤗 Деплоймент на HuggingFace Spaces
31
+
32
+ ### 1. Створення Space
33
+ 1. Перейдіть на [HuggingFace Spaces](https://huggingface.co/spaces)
34
+ 2. Натисніть "Create new Space"
35
+ 3. Оберіть **Gradio** як SDK
36
+ 4. Завантажте файли проекту
37
+
38
+ ### 2. Налаштування змінних оточення
39
+ 1. В налаштуваннях Space перейдіть в розділ **Variables and secrets**
40
+ 2. Додайте змінну `GEMINI_API_KEY` з вашим API ключем
41
+
42
+ ### 3. Файлова структура для HuggingFace
43
+ ```
44
+ your-space/
45
+ ├── app.py
46
+ ├── requirements.txt
47
+ ├── .env.example
48
+ └── README.md
49
+ ```
50
+
51
+ ## 🧪 Тестування
52
+
53
+ ### Медичний режим
54
+ Спробуйте повідомлення:
55
+ - "У мене болить груди та важко дихати"
56
+ - "Високий тиск 180/100, що робити?"
57
+ - "Піднялася температура до 39"
58
+
59
+ ### Lifestyle режим
60
+ Спробуйте повідомлення:
61
+ - "Хочу почати займатися спортом"
62
+ - "Як правильно харчуватися при діабеті?"
63
+ - "Допоможіть скласти план тренувань"
64
+
65
+ ### Змішані запити
66
+ - "Чи можна мені бігати з моїм серцем?"
67
+ - "Які вправи безпечні при гіпертонії?"
68
+
69
+ ## 📋 Архітектура
70
+
71
+ ### Компоненти
72
+ - **SessionController** - оркестратор режимів (JSON рішення)
73
+ - **MedicalAssistant** - медичні консультації та тріаж
74
+ - **LifestyleAssistant** - coaching з оновленням профілю
75
+ - **GradioInterface** - візуальний інтерфейс
76
+
77
+ ### Потік даних
78
+ ```
79
+ Повідомлення → SessionController → Medical/Lifestyle Assistant → Відповідь + Профіль
80
+ ```
81
+
82
+ ## ⚠️ Важливо
83
+
84
+ - Це **тестовий MVP**, не для реального медичного використання
85
+ - Завжди консультуйтесь з лікарем при серйозних симптомах
86
+ - API ключ тримайте в безпеці
87
+
88
+ ## 🔧 Налагодження
89
+
90
+ Якщо виникають проблеми:
91
+ 1. Перевірте наявність `GEMINI_API_KEY` в .env файлі
92
+ 2. Переконайтесь що всі залежності встановлені
93
+ 3. Перегляньте логи в консолі
94
+
95
+ ## 📞 Підтримка
96
+
97
+ При виникненні питань створюйте issue в репозиторії проекту.
app.py ADDED
@@ -0,0 +1,478 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import gradio as gr
4
+ from datetime import datetime
5
+ from dataclasses import dataclass, asdict
6
+ from typing import List, Dict, Optional
7
+ from google import genai
8
+ from google.genai import types
9
+ from dotenv import load_dotenv
10
+
11
+ from dotenv import load_dotenv
12
+ try:
13
+ from app_config import GRADIO_CONFIG, API_CONFIG
14
+ except ImportError:
15
+ # Fallback конфігурація якщо файл відсутній
16
+ GRADIO_CONFIG = {"theme": "soft", "show_api": False}
17
+ API_CONFIG = {"gemini_model": "gemini-2.5-flash", "temperature": 0.3}
18
+
19
+ # Завантаження змінних оточення з .env файлу
20
+ load_dotenv()
21
+
22
+ @dataclass
23
+ class ClinicalBackground:
24
+ patient_id: str
25
+ conditions: List[str]
26
+ medications: List[str]
27
+ allergies: List[str]
28
+ current_symptoms: List[str]
29
+ vital_signs: Dict[str, str]
30
+
31
+ @dataclass
32
+ class LifestyleProfile:
33
+ exercise_preferences: List[str]
34
+ limitations: List[str]
35
+ dietary_notes: List[str]
36
+ goals: List[str]
37
+ journey_summary: str
38
+ last_session_summary: str
39
+ progress_metrics: Dict[str, str]
40
+
41
+ @dataclass
42
+ class ChatMessage:
43
+ timestamp: str
44
+ role: str # "user" or "assistant"
45
+ message: str
46
+ mode: str # "medical", "lifestyle", or "controller"
47
+ metadata: Dict = None
48
+
49
+ @dataclass
50
+ class SessionState:
51
+ current_mode: str # "medical", "lifestyle", "none"
52
+ is_active_session: bool
53
+ session_start_time: Optional[str]
54
+ last_controller_decision: Dict
55
+
56
+ class GeminiAPI:
57
+ def __init__(self):
58
+ self.client = genai.Client(
59
+ api_key=os.environ.get("GEMINI_API_KEY"),
60
+ )
61
+ self.model = os.getenv("GEMINI_MODEL", API_CONFIG.get("gemini_model", "gemini-2.5-flash"))
62
+
63
+ def generate_response(self, system_prompt: str, user_prompt: str, temperature: float = None) -> str:
64
+ """Генерує відповідь від Gemini"""
65
+ if temperature is None:
66
+ temperature = API_CONFIG.get("temperature", 0.3)
67
+
68
+ try:
69
+ contents = [
70
+ types.Content(
71
+ role="user",
72
+ parts=[types.Part.from_text(text=user_prompt)],
73
+ ),
74
+ ]
75
+
76
+ config = types.GenerateContentConfig(
77
+ temperature=temperature,
78
+ system_instruction=[
79
+ types.Part.from_text(text=system_prompt),
80
+ ],
81
+ )
82
+
83
+ response = ""
84
+ for chunk in self.client.models.generate_content_stream(
85
+ model=self.model,
86
+ contents=contents,
87
+ config=config,
88
+ ):
89
+ response += chunk.text
90
+
91
+ return response.strip()
92
+ except Exception as e:
93
+ return f"Помилка API: {str(e)}"
94
+
95
+ class SessionController:
96
+ def __init__(self, api: GeminiAPI):
97
+ self.api = api
98
+
99
+ def make_decision(self, user_message: str, chat_history: List[ChatMessage],
100
+ clinical_background: ClinicalBackground, current_state: SessionState) -> Dict:
101
+ """Приймає рішення про режим сесії"""
102
+
103
+ system_prompt = """Ти - Session Controller для медичного додатку з lifestyle coaching.
104
+
105
+ ТВОЄ ЗАВДАННЯ: Проаналізувати повідомлення пацієнта і прийняти рішення про режим роботи.
106
+
107
+ РЕЖИМИ:
108
+ - medical: медичні симптоми, скарги, ургентні стани
109
+ - lifestyle: фізична активність, харчування, спосіб життя, мотивація
110
+ - none: завершення сесії або неясний контекст
111
+
112
+ RED FLAGS (завжди -> medical):
113
+ - біль у грудях, задишка у спокої
114
+ - високий АТ (>180/120), низький (<80/50)
115
+ - синкопе, запаморочення
116
+ - різкий набряк, набір ваги
117
+ - симптомна гіпо/гіперглікемія
118
+
119
+ ВІДПОВІДАЙ ЛИШЕ У ФОРМАТІ JSON:
120
+ {
121
+ "action": "start_medical|start_lifestyle|continue_current|end_session",
122
+ "mode": "medical|lifestyle|none",
123
+ "reasoning": "коротке пояснення українською",
124
+ "escalation_needed": true/false
125
+ }"""
126
+
127
+ # Формуємо контекст
128
+ history_text = "\n".join([f"{msg.role}: {msg.message}" for msg in chat_history[-5:]])
129
+ clinical_text = f"Стани: {', '.join(clinical_background.conditions)}"
130
+
131
+ user_prompt = f"""
132
+ КЛІНІЧНИЙ КОНТЕКСТ: {clinical_text}
133
+
134
+ ПОТОЧНИЙ СТАН СЕСІЇ: режим={current_state.current_mode}, активна={current_state.is_active_session}
135
+
136
+ ІСТОРІЯ ЧАТУ:
137
+ {history_text}
138
+
139
+ НОВЕ ПОВІДОМЛЕННЯ ПАЦІЄНТА: {user_message}
140
+
141
+ Прийми рішення про режим роботи:"""
142
+
143
+ response = self.api.generate_response(system_prompt, user_prompt, temperature=0.1)
144
+
145
+ try:
146
+ # Очищуємо відповідь від markdown
147
+ clean_response = response.replace("```json", "").replace("```", "").strip()
148
+ decision = json.loads(clean_response)
149
+ return decision
150
+ except:
151
+ # Fallback рішення
152
+ return {
153
+ "action": "start_medical",
154
+ "mode": "medical",
155
+ "reasoning": "Помилка парсингу - перенаправлення до медичного режиму для безпеки",
156
+ "escalation_needed": True
157
+ }
158
+
159
+ class MedicalAssistant:
160
+ def __init__(self, api: GeminiAPI):
161
+ self.api = api
162
+
163
+ def generate_response(self, user_message: str, chat_history: List[ChatMessage],
164
+ clinical_background: ClinicalBackground) -> str:
165
+ """Генерує медичну відповідь"""
166
+
167
+ system_prompt = """Ти - досвідчений медичний асистент для пацієнтів з хронічними захворюваннями.
168
+
169
+ ПРИНЦИПИ:
170
+ - Безпека пацієнта - головний пріоритет
171
+ - Не ставиш діагнози, не призначаєш лікування
172
+ - Рекомендуєш звернення до лікаря при червоних прапорцях
173
+ - Даєш загальні поради з управління хронічними станами
174
+ - Відповідаєш українською мовою
175
+
176
+ При УРГЕНТНИХ симптомах - рекомендуй негайне звернення до медзакладу."""
177
+
178
+ # Контекст
179
+ conditions = ", ".join(clinical_background.conditions)
180
+ medications = ", ".join(clinical_background.medications) if clinical_background.medications else "не вказані"
181
+ history_text = "\n".join([f"{msg.role}: {msg.message}" for msg in chat_history[-3:]])
182
+
183
+ user_prompt = f"""
184
+ МЕДИЧНИЙ ПРОФІЛЬ ПАЦІЄНТА:
185
+ - Захворювання: {conditions}
186
+ - Медикаменти: {medications}
187
+ - Алергії: {", ".join(clinical_background.allergies) if clinical_background.allergies else "немає"}
188
+
189
+ ІСТОРІЯ РОЗМОВИ:
190
+ {history_text}
191
+
192
+ ПИТАННЯ ПАЦІЄНТА: {user_message}
193
+
194
+ Надай медичну консультацію:"""
195
+
196
+ return self.api.generate_response(system_prompt, user_prompt)
197
+
198
+ class LifestyleAssistant:
199
+ def __init__(self, api: GeminiAPI):
200
+ self.api = api
201
+
202
+ def generate_response(self, user_message: str, chat_history: List[ChatMessage],
203
+ clinical_background: ClinicalBackground, lifestyle_profile: LifestyleProfile) -> tuple[str, LifestyleProfile]:
204
+ """Генерує lifestyle відповідь та оновлює профіль"""
205
+
206
+ system_prompt = """Ти - lifestyle coach для пацієнтів з хронічними захворюваннями.
207
+
208
+ ПРИНЦИПИ:
209
+ - Безпечні, поступові зміни з урахуванням медичних обмежень
210
+ - Персоналізація на основі профілю пацієнта
211
+ - Позитивне підкріплення та реалістичні цілі
212
+ - Мотивація через малі кроки прогресу
213
+ - Відповідаєш українською мовою
214
+
215
+ УВАГА до медичних обмежень:
216
+ - ХСН: уникай інтенсивних навантажень
217
+ - АГ: контроль солі, стрес-менеджмент
218
+ - ЦД2: контроль вуглеводів, регулярність
219
+
220
+ В кінці кожної сесії пропонуй конкретний план дій та час наступної зустрічі."""
221
+
222
+ # Контекст
223
+ conditions = ", ".join(clinical_background.conditions)
224
+ goals = ", ".join(lifestyle_profile.goals) if lifestyle_profile.goals else "не визначені"
225
+ limitations = ", ".join(lifestyle_profile.limitations) if lifestyle_profile.limitations else "немає"
226
+
227
+ history_text = "\n".join([f"{msg.role}: {msg.message}" for msg in chat_history[-3:]])
228
+
229
+ user_prompt = f"""
230
+ МЕДИЧНИЙ КОНТЕКСТ: {conditions}
231
+
232
+ LIFESTYLE ПРОФІЛЬ:
233
+ - Цілі: {goals}
234
+ - Обмеження: {limitations}
235
+ - Уподобання: {", ".join(lifestyle_profile.exercise_preferences) if lifestyle_profile.exercise_preferences else "не вказані"}
236
+ - Попередня сесія: {lifestyle_profile.last_session_summary}
237
+
238
+ ІСТОРІЯ РОЗМОВИ:
239
+ {history_text}
240
+
241
+ ПОВІДОМЛЕННЯ ПАЦІЄНТА: {user_message}
242
+
243
+ Проведи lifestyle коучинг:"""
244
+
245
+ response = self.api.generate_response(system_prompt, user_prompt)
246
+
247
+ # Простий update профілю - додаємо до journey summary
248
+ updated_profile = lifestyle_profile
249
+ if user_message and response:
250
+ updated_profile.last_session_summary = f"Обговорили: {user_message[:100]}..."
251
+ updated_profile.journey_summary += f" Сесія {datetime.now().strftime('%d.%m')}: {user_message[:50]}..."
252
+
253
+ return response, updated_profile
254
+
255
+ class LifestyleJourneyApp:
256
+ def __init__(self):
257
+ self.api = GeminiAPI()
258
+ self.controller = SessionController(self.api)
259
+ self.medical_assistant = MedicalAssistant(self.api)
260
+ self.lifestyle_assistant = LifestyleAssistant(self.api)
261
+
262
+ # Ініціалізація даних пацієнта
263
+ self.clinical_background = ClinicalBackground(
264
+ patient_id="test_001",
265
+ conditions=["Хронічна серцева недостатність", "Артеріальна гіпертензія", "Цукровий діабет 2 типу"],
266
+ medications=["Еналаприл 10мг", "Метформін 500мг"],
267
+ allergies=["Пеніцилін"],
268
+ current_symptoms=[],
269
+ vital_signs={"АТ": "140/90", "ЧСС": "72", "Глюкоза": "8.2"}
270
+ )
271
+
272
+ self.lifestyle_profile = LifestyleProfile(
273
+ exercise_preferences=["ходьба на свіжому повітрі"],
274
+ limitations=["уникати високоінтенсивних навантажень через ХСН"],
275
+ dietary_notes=["низькосольова дієта", "контроль вуглеводів"],
276
+ goals=["покращити витривалість", "контролювати АТ та цукор"],
277
+ journey_summary="Початок lifestyle journey",
278
+ last_session_summary="",
279
+ progress_metrics={}
280
+ )
281
+
282
+ self.chat_history: List[ChatMessage] = []
283
+ self.session_state = SessionState(
284
+ current_mode="none",
285
+ is_active_session=False,
286
+ session_start_time=None,
287
+ last_controller_decision={}
288
+ )
289
+
290
+ def process_message(self, message: str, history):
291
+ """Основна логіка обробки повідомлень"""
292
+ if not message.strip():
293
+ return history, self._get_status_info()
294
+
295
+ # 1. Controller приймає рішення
296
+ decision = self.controller.make_decision(
297
+ message, self.chat_history, self.clinical_background, self.session_state
298
+ )
299
+
300
+ self.session_state.last_controller_decision = decision
301
+
302
+ # 2. Додаємо повідомлення користувача до історії
303
+ user_msg = ChatMessage(
304
+ timestamp=datetime.now().strftime("%H:%M"),
305
+ role="user",
306
+ message=message,
307
+ mode=decision.get("mode", "unknown")
308
+ )
309
+ self.chat_history.append(user_msg)
310
+
311
+ # 3. Генеруємо відповідь залежно від режиму
312
+ if decision["mode"] == "medical":
313
+ self.session_state.current_mode = "medical"
314
+ self.session_state.is_active_session = True
315
+
316
+ response = self.medical_assistant.generate_response(
317
+ message, self.chat_history, self.clinical_background
318
+ )
319
+
320
+ elif decision["mode"] == "lifestyle":
321
+ self.session_state.current_mode = "lifestyle"
322
+ self.session_state.is_active_session = True
323
+
324
+ response, self.lifestyle_profile = self.lifestyle_assistant.generate_response(
325
+ message, self.chat_history, self.clinical_background, self.lifestyle_profile
326
+ )
327
+
328
+ else:
329
+ self.session_state.current_mode = "none"
330
+ self.session_state.is_active_session = False
331
+ response = "Будь ласка, уточніть ваше питання. Я можу допомогти з медичними питаннями або питаннями способу життя."
332
+
333
+ # 4. Додаємо відповідь асистента
334
+ assistant_msg = ChatMessage(
335
+ timestamp=datetime.now().strftime("%H:%M"),
336
+ role="assistant",
337
+ message=response,
338
+ mode=self.session_state.current_mode
339
+ )
340
+ self.chat_history.append(assistant_msg)
341
+
342
+ # 5. Оновлюємо Gradio історію
343
+ history.append([message, response])
344
+
345
+ return history, self._get_status_info()
346
+
347
+ def _get_status_info(self) -> str:
348
+ """Повертає інформацію про стан сесії"""
349
+ decision = self.session_state.last_controller_decision
350
+
351
+ status = f"""
352
+ 📊 **СТАН СЕСІЇ**
353
+ • Режим: {self.session_state.current_mode.upper()}
354
+ • Активна: {'✅' if self.session_state.is_active_session else '❌'}
355
+
356
+ 🧠 **ОСТАННЄ РІШЕННЯ CONTROLLER:**
357
+ • Дія: {decision.get('action', 'N/A')}
358
+ • Обґрунтування: {decision.get('reasoning', 'N/A')}
359
+ • Ескалація: {'🚨' if decision.get('escalation_needed') else '✅'}
360
+
361
+ 👤 **ПАЦІЄНТ:**
362
+ • Стани: {', '.join(self.clinical_background.conditions)}
363
+ • Lifestyle цілі: {', '.join(self.lifestyle_profile.goals) if self.lifestyle_profile.goals else 'Не встановлені'}
364
+ """
365
+ return status
366
+
367
+ def reset_session(self):
368
+ """Скидання сесії"""
369
+ self.chat_history = []
370
+ self.session_state = SessionState(
371
+ current_mode="none",
372
+ is_active_session=False,
373
+ session_start_time=None,
374
+ last_controller_decision={}
375
+ )
376
+ return [], self._get_status_info()
377
+
378
+ # Створення Gradio інтерфейсу
379
+ def create_app():
380
+ app = LifestyleJourneyApp()
381
+
382
+ # Використовуємо конфігурацію для Gradio
383
+ theme_name = GRADIO_CONFIG.get("theme", "soft")
384
+ if theme_name.lower() == "soft":
385
+ theme = gr.themes.Soft()
386
+ elif theme_name.lower() == "default":
387
+ theme = gr.themes.Default()
388
+ else:
389
+ theme = gr.themes.Soft() # fallback
390
+
391
+ with gr.Blocks(
392
+ title=GRADIO_CONFIG.get("title", "Lifestyle Journey MVP"),
393
+ theme=theme,
394
+ analytics_enabled=False
395
+ ) as demo:
396
+ gr.Markdown("# 🏥 Lifestyle Journey MVP")
397
+ gr.Markdown("Тестовий чат-бот з медичним асистентом та lifestyle коучингом")
398
+
399
+ with gr.Row():
400
+ with gr.Column(scale=2):
401
+ chatbot = gr.Chatbot(
402
+ label="💬 Розмова з асистентом",
403
+ height=400,
404
+ show_copy_button=True
405
+ )
406
+
407
+ with gr.Row():
408
+ msg = gr.Textbox(
409
+ label="Ваше повідомлення",
410
+ placeholder="Напишіть своє питання...",
411
+ scale=4
412
+ )
413
+ send_btn = gr.Button("📤 Надіслати", scale=1)
414
+
415
+ clear_btn = gr.Button("🗑️ Очистити чат")
416
+
417
+ with gr.Column(scale=1):
418
+ status_box = gr.Markdown(
419
+ value=app._get_status_info(),
420
+ label="📊 Статус системи"
421
+ )
422
+
423
+ # Обробники подій
424
+ def handle_message(message, history):
425
+ return app.process_message(message, history)
426
+
427
+ def handle_clear():
428
+ return app.reset_session()
429
+
430
+ send_btn.click(
431
+ handle_message,
432
+ inputs=[msg, chatbot],
433
+ outputs=[chatbot, status_box]
434
+ ).then(
435
+ lambda: "",
436
+ outputs=[msg]
437
+ )
438
+
439
+ msg.submit(
440
+ handle_message,
441
+ inputs=[msg, chatbot],
442
+ outputs=[chatbot, status_box]
443
+ ).then(
444
+ lambda: "",
445
+ outputs=[msg]
446
+ )
447
+
448
+ clear_btn.click(
449
+ handle_clear,
450
+ outputs=[chatbot, status_box]
451
+ )
452
+
453
+ return demo
454
+
455
+ if __name__ == "__main__":
456
+ # API ключ завантажується з .env файлу
457
+ # Створіть файл .env з: GEMINI_API_KEY=your_api_key_here
458
+
459
+ if not os.getenv("GEMINI_API_KEY"):
460
+ print("⚠️ GEMINI_API_KEY не знайдено в змінних оточення!")
461
+ print("Для локального запуску створіть .env файл з API ключем")
462
+
463
+ demo = create_app()
464
+
465
+ # Параметри для HuggingFace Spaces
466
+ is_hf_space = os.getenv("SPACE_ID") is not None
467
+
468
+ if is_hf_space:
469
+ # Конфігурація для HuggingFace Spaces
470
+ demo.launch(
471
+ server_name="0.0.0.0",
472
+ server_port=7860,
473
+ show_api=False,
474
+ show_error=True
475
+ )
476
+ else:
477
+ # Локальний запуск
478
+ demo.launch(share=True, debug=True)
app_config.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Конфігурація для HuggingFace Spaces деплойменту
3
+ """
4
+
5
+ # HuggingFace Spaces метадані
6
+ SPACE_CONFIG = {
7
+ "title": "🏥 Lifestyle Journey MVP",
8
+ "emoji": "🏥",
9
+ "colorFrom": "blue",
10
+ "colorTo": "green",
11
+ "sdk": "gradio",
12
+ "sdk_version": "4.0.0",
13
+ "app_file": "app.py",
14
+ "pinned": False,
15
+ "license": "mit"
16
+ }
17
+
18
+ # Gradio конфігурація
19
+ GRADIO_CONFIG = {
20
+ "theme": "soft",
21
+ "show_api": False,
22
+ "show_error": True,
23
+ "height": 600,
24
+ "title": "Lifestyle Journey MVP"
25
+ }
26
+
27
+ # API конфігурація
28
+ API_CONFIG = {
29
+ "gemini_model": "gemini-2.5-flash",
30
+ "temperature": 0.3,
31
+ "max_tokens": 2048
32
+ }
clinical_background.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "patient_summary": {
3
+ "active_problems": [
4
+ "Nausea (01/02/2025)",
5
+ "Hypokalemia (01/07/2025)",
6
+ "Type 2 diabetes mellitus with other diabetic neurological complication (01/07/2025)",
7
+ "Right leg stump pain (06/17/2024)",
8
+ "Foot ulcerations (10/07/2024)",
9
+ "Chest pain (12/22/2024)",
10
+ "Muscle cramps (08/19/2024)",
11
+ "GERD (gastroesophageal reflux disease) (08/19/2024)"
12
+ ],
13
+ "past_medical_history": [
14
+ "Type 2 diabetes w diabetic peripheral angiopath w/o gangrene",
15
+ "Essential (primary) hypertension",
16
+ "Hyperlipidemia, unspecified",
17
+ "Bipolar disorder, unspecified",
18
+ "Attention-deficit hyperactivity disorder, unspecified type",
19
+ "Gastro-esophageal reflux disease without esophagitis",
20
+ "PVD",
21
+ "Osteomyelitis",
22
+ "OSA",
23
+ "Diabetic neuropathy",
24
+ "Personality disorder in adult (06/28/2016)",
25
+ "Bipolar disorder in remission (CMS/HCC) (02/04/2016)",
26
+ "GAD (generalized anxiety disorder) (10/30/2015)",
27
+ "OCD (obsessive compulsive disorder) (10/30/2015)",
28
+ "Reflux esophagitis (10/30/2015)",
29
+ "Gastritis (10/30/2015)",
30
+ "Dysphagia (10/30/2015)",
31
+ "ADHD (attention deficit hyperactivity disorder), inattentive type (10/30/2015)",
32
+ "Diabetic ulcer with osteomyelitis (08/21/2020)",
33
+ "Low back pain, MVA (10/10/2012)",
34
+ "Muscle spasm of back",
35
+ "Diabetic foot ulcer associated with type 2 diabetes mellitus",
36
+ "Right below knee amputation (10/04/2022)",
37
+ "Knee, arthroscopic, Rt (2009)",
38
+ "Umbilical herniorrhaphy (2009)",
39
+ "Tonsillectomy",
40
+ "Hernia repair (09/22/2020)",
41
+ "Foot surgery (09/22/2020)"
42
+ ],
43
+ "current_medications": [
44
+ "Amlodipine - 5 mg - tablet - Once a day",
45
+ "Acetaminophen - 325 MG - Tablet - as needed Orally every 4 hrs",
46
+ "busPIRone HCl - 30 MG - Tablet - 2 times a day",
47
+ "CPAP Machine - Machine - as directed nightly",
48
+ "Cyclobenzaprine HCl - 10 MG - Tablet - 3 times a day prn",
49
+ "Dexcom G6 Receiver - Device - as directed",
50
+ "Dexcom G6 Sensor - Device - as directed",
51
+ "Dexcom G6 Transmitter - Miscellaneous - as directed",
52
+ "EPINEPHrine - 0.3 MG/0.3ML - Solution Auto-injector - as directed Injection once",
53
+ "Famotidine - 40 MG - Tablet - 1 tablet at bedtime Orally Once a day",
54
+ "Ferrous Sulfate - 325 (65 Fe) MG - Tablet - 1 tablet Orally Once a day",
55
+ "hydrOXYzine Pamoate - 50 MG - Capsule - 1 cap(s) orally qhs",
56
+ "LaMICtal - 200 MG - Tablet - 1 tab orally Once a day",
57
+ "Magnesium Oxide - 500 MG - Tablet - as directed Orally",
58
+ "Montelukast Sodium - 10 MG - Tablet - 1 tablet Orally Once a day",
59
+ "NovoLOG - 100 UNIT/ML - Solution - as directed Injection",
60
+ "Omeprazole - 40 MG - Capsule Delayed Release - 1 capsule 30 minutes before morning meal Orally Once a day",
61
+ "Ondansetron HCl - 8 MG - Tablet - 1 tablet as needed Orally three times a day As needed",
62
+ "Ozempic - 2 MG/DOSE - Solution Pen-injector - INJECT 2 MG SUBCUTANEOUSLY EVERY 7 DAYS Subcutaneous",
63
+ "Pen Needles - 31G X 5 MM - Miscellaneous - 1 SQ bid",
64
+ "Potassium Chloride ER - 10 MEQ - Capsule Extended Release - 1 capsule with food Orally Twice a day (Started 01/07/2025, replacing tablet form)",
65
+ "Ritalin - 20 MG - Tablet - 2 times a day",
66
+ "Rosuvastatin Calcium - 20 MG - Tablet - 1 tab(s) orally once a day",
67
+ "Spironolactone - 100 MG - Tablet - 1 tablet Orally Once a day",
68
+ "Fluticasone Propionate - 50 MCG/ACT - Suspension - 1 spray in each nostril Nasally bid prn",
69
+ "Metoclopramide HCl - 10 MG - Tablet - 1 tablet before meals, Orally, Twice a day (Started 01/07/2025)"
70
+ ],
71
+ "allergies": "Clindamycin: sob - Allergy. No known allergies"
72
+ },
73
+ "vital_signs_and_measurements": [
74
+ "Blood Pressure: 148/98 (01/07/2025)",
75
+ "Blood Pressure Other: 154/106 (01/07/2025)",
76
+ "Height: 1.805 m (71.1\") (01/07/2025)",
77
+ "Weight: 109.8 kg (242 lb) (01/07/2025)",
78
+ "BMI: 33.65 kg/m² (01/07/2025)",
79
+ "Temperature: 97.3 (01/07/2025)",
80
+ "Heart Rate: 92 (01/07/2025)",
81
+ "Respiratory Rate: 16 (01/07/2025)"
82
+ ],
83
+ "laboratory_results": [
84
+ "POTASSIUM - 3.3 mmol/L (12/22/2024)"
85
+ ],
86
+ "imaging_studies_and_diagnostic_procedures": [
87
+ "XR chest 1 view: No acute cardiopulmonary process. - 12/22/2024",
88
+ "ECG 12 lead EKG: sinus rhythm with left axis deviation with no ST elevation or abnormal T wave inversion. Similar compared to prior EKG from 8/11/2023. - 12/22/2024",
89
+ "ECG 12 lead EKG: sinus rhythm with left axis deviation with no ST elevation. Artifact in lead II. No significant changes compared to EKG earlier in the day. - 12/22/2024",
90
+ "ECG 12 Lead: Sinus rhythm, left axis deviation, RSR' in V1 or V2, right VCD or RVH, Baseline wander in lead(s) V3 (12/22/2024)",
91
+ "ECG: Sinus rhythm at 82 bpm. First-degree AV block. Axis -62 degrees. No ST elevations or depressions. (12/20/24)",
92
+ "ECG 12 lead: Sinus rhythm, RSR' in V1 or V2, right VCD or RVH, Inferior infarct, old, Lateral leads are also involved (12/22/24)",
93
+ "ECG 12 lead: Sinus rhythm, Left axis deviation, RSR'in V1 or V2, right VCD or RVH, Baseline wander in lead(s) V3 (12/22/24)"
94
+ ],
95
+ "assessment_and_plan": "On 01/07/2025, Jeremy presented for an ER follow-up due to vomiting on 12/20/24 and chest pain on 12/22/24. He continues to experience shaking, cramping, and nausea. His potassium level was low at 3.3 on 12/20/24. The plan includes stopping Potassium Chloride ER Tablet Extended Release and starting Potassium Chloride ER Capsule Extended Release, 10 MEQ, twice a day. A potassium serum lab is ordered. Metoclopramide HCl 10 MG tablet twice a day before meals was started for nausea. Ondansetron HCl 8 MG tablet three times a day as needed was refilled. Follow up is scheduled as needed for acute issues.",
96
+ "critical_alerts": [
97
+ "Life endangering medical noncompliance (03/06/2023)"
98
+ ],
99
+ "social_history": {
100
+ "smoking_status": "Never",
101
+ "alcohol_use": "Yes, 2-3 times a week",
102
+ "caffeine_use": {
103
+ "soda": "2-3 per day",
104
+ "energy_drinks": "1 per day"
105
+ }
106
+ },
107
+ "care_management": [
108
+ "Nephrology continues to follow for AKI.",
109
+ "Patient from home independent with family and follows at wound care center outpatient.",
110
+ "Jessica Lea Falvo Lang, MD is the patient's PCP.",
111
+ "Dishon Kamwesa, APRN.CNP of Hartville Family Physicians is the patient's PCP.",
112
+ "May be good candidate for Care Management.",
113
+ "Kathy Fox is the CHCI Care Manager, Date care manager notified: 05/09/2022."
114
+ ],
115
+ "recent_clinical_events_and_encounters": [
116
+ "2025-01-07: ER follow-up with Dishon Kamwesa, NP-C for vomiting on 12/20/24 and chest pain on 12/22/24. Potassium Chloride ER Tablet was stopped and Potassium Chloride ER Capsule was started. Metoclopramide was started for nausea and Ondansetron was refilled.",
117
+ "2025-01-02: Telephone encounter with Weiss Clinical Phone Triage LPN, Samantha. Patient reports nausea and vomiting and requests medication. ER follow up scheduled for 2025-01-07. Ondansetron 8 mg tablet TID prn prescribed.",
118
+ "2024-12-25: University Hospitals encounter. Follow-up with Jessica Lee Falvo Lang, MD scheduled as soon as possible for a visit in 3 days.",
119
+ "2024-12-23: Telephone encounter with Turkall ED Transition of Care Coordinator, Sharon A for ER TOC UH 12/22/24 Chest pain. Reports scanned in. Provider: Falvo Lang, Jessica L. LM to see how pt. is doing and if needs a F/U appt. WEB message sent.",
120
+ "2024-12-22: Emergency department visit for chest pain and shortness of breath. Discharged home with referral to outpatient stress test.",
121
+ "2024-12-20: Emergency department visit at Aultman Hospital for vomiting. Discharged home with prescriptions for ondansetron, promethazine, and metoclopramide. Follow up with Jessica Falvo-Lang, MD in 2-4 days."
122
+ ]
123
+ }
diagram/complete-flow-diagram.mermaid ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flowchart TB
2
+ %% Стилізація
3
+ classDef new fill:#fff3e0,stroke:#ff9800,stroke-width:3px
4
+ classDef existing fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
5
+ classDef critical fill:#ffebee,stroke:#f44336,stroke-width:3px
6
+ classDef success fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
7
+
8
+ Start([Повідомлення пацієнта])
9
+ Start --> L0_Check
10
+ Start --> L1_Medical
11
+ Start --> MRE
12
+
13
+
14
+ %% MRE
15
+ MRE["MRE"]:::existing
16
+ MRE --> |"MRE Response"|Medical_Flow
17
+ %% Level 0 Decision Block
18
+
19
+
20
+ L0_Check["LLM Lifestyle Detector"]:::new
21
+
22
+ %% L0_Check -->|"❌ NO<br/>Medical/Undefined"| L1_Medical
23
+ L0_Check -->|"✅ YES/ ❌ NO<br/>Lifestyle Trigger"| Post_Check
24
+ %% L0_Check -->|"⚠️ MIXED<br/>Symptoms + Lifestyle"| L1_Mixed
25
+
26
+ %% %% Safety Pre-check for Lifestyle
27
+ %% Safety_Pre{"Quick Safety<br/>Check"}:::critical
28
+ %% Safety_Pre -->|"Red flags"| L1_Medical
29
+ %% Safety_Pre -->|"Safe"| Lifestyle_Mode
30
+
31
+ %% Medical Path (Level 1)
32
+ L1_Medical["LLM First prompt <br/>(Suggested message + Escalation)"]:::existing
33
+ L1_Medical -->|"Suggested message"| Medical_Flow
34
+ L1_Medical -->|"🚨 ESCALATION=TRUE/FALSE"| Post_Check
35
+
36
+ %% Mixed Path (Level 1)
37
+ %% L1_Mixed{"Level 1<br/>Symptom Assessment<br/>[EXISTING]"}:::existing
38
+ %% L1_Mixed -->|"🚨 URGENT"| Provider_Alert
39
+ %% L1_Mixed -->|"✅ NON-URGENT"| Lifestyle_After_Clear
40
+
41
+ %% Provider Escalation
42
+ %% Provider_Alert["🚨 PROVIDER ALERT<br/>Urgent Response"]:::critical
43
+ %% Provider_Alert --> End_Medical
44
+
45
+ %% Post Level 1 Check
46
+ Post_Check{"Lifestyle<br/>Need and Possible?"}:::new
47
+ Post_Check -->|"NO"| Medical_Flow
48
+ Post_Check -->|"YES"| Lifestyle_Mode
49
+
50
+ %% Medical Flow
51
+ Medical_Flow["LLM Second Prompt<br/>Recheck MRE"]:::existing
52
+ Medical_Flow --> End_Medical
53
+
54
+ %% Lifestyle After Medical Clearance
55
+ %% Lifestyle_After_Clear["✅ Medical Cleared<br/>Safe for Lifestyle"]:::success
56
+ %% Lifestyle_After_Clear --> Lifestyle_Mode
57
+
58
+ %% Lifestyle Mode Activation
59
+ Lifestyle_Mode["🌟 LIFESTYLE MODE ACTIVE"]:::new
60
+ Lifestyle_Mode --> Load_Profile
61
+
62
+
63
+ Load_Profile["📊 Load Full<br/>Patient Profile"]:::new
64
+ Load_Profile --> Lifestyle_LLM
65
+
66
+ Lifestyle_LLM["💚 Lifestyle LLM<br/>Coaching Response"]:::new
67
+ Lifestyle_LLM --> Update_Profile
68
+
69
+ Update_Profile["🔄 Update Profile<br/>Track Progress"]:::new
70
+ Update_Profile --> Session_Check
71
+
72
+ Session_Check{"Continue<br/>Session?"}:::new
73
+ Session_Check -->|"YES"| Lifestyle_LLM
74
+ Session_Check -->|"NO"| End_Session
75
+
76
+ End_Session["Session End<br/>✅ CE Re-enabled"]:::new
77
+ End_Session --> End_Lifestyle
78
+
79
+ %% End Points
80
+ End_Medical[["LLM Response<br/>to Patient"]]:::existing
81
+ End_Lifestyle[["Lifestyle Response<br/>to Patient"]]:::success
82
+
diagram/lifestyle-activation-logic.mermaid ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flowchart TD
2
+ %% Стилізація
3
+ classDef trigger fill:#e8f5e9,stroke:#4caf50,stroke-width:3px
4
+ classDef classifier fill:#fff3e0,stroke:#ff9800,stroke-width:2px
5
+ classDef prompt fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
6
+ classDef decision fill:#ffebee,stroke:#f44336,stroke-width:2px
7
+ classDef lifestyle fill:#f3e5f5,stroke:#9c27b0,stroke-width:3px
8
+
9
+ %% Три способи активації
10
+ Start([Start])
11
+ Start --> CheckTriggers
12
+
13
+ CheckTriggers{Checking triggers}
14
+
15
+ %% ТРИГЕР 1: Scheduled
16
+ CheckTriggers -->|"📅 Scheduled"| Trigger1["1️⃣ MRE Scheduled Basis<br/>(e.g., once per week)"]:::trigger
17
+ Trigger1 --> LifestylePromptDirect1[["💚 LIFESTYLE PROMPT"]]:::lifestyle
18
+
19
+ %% ТРИГЕР 2: Follow-up
20
+ CheckTriggers -->|"🔄 Follow-up"| Trigger2["2️⃣ LLM requested follow-up<br/>in previous session"]:::trigger
21
+ Trigger2 --> LifestylePromptDirect2[["💚 LIFESTYLE PROMPT"]]:::lifestyle
22
+
23
+ %% ТРИГЕР 3: Patient Initiated
24
+ CheckTriggers -->|"💬 Message"| Trigger3["3️⃣ Patient message"]:::trigger
25
+
26
+ %% Детальна логіка для patient-initiated
27
+ Trigger3 --> Step3_1["3.1 Check Lifestyle Trigger<br/>(keywords, patterns)"]:::classifier
28
+
29
+ Step3_1 -->|"NO lifestyle markers"| RegularFlow["Regular Medical Flow"]
30
+ Step3_1 -->|"YES lifestyle markers"| Step3_2
31
+
32
+ Step3_2["3.2 Gemini Classifier<br/>(type of MRE/CE message)"]:::classifier
33
+ Step3_2 --> Step3_3
34
+
35
+ Step3_3["3.3 FIRST PROMPT<br/>Generate: Suggested message + Escalation flag"]:::prompt
36
+ Step3_3 --> EscalationCheck
37
+
38
+ EscalationCheck{"3.4 Check Escalation Flag"}:::decision
39
+
40
+ %% Path 4.1: Escalation = TRUE
41
+ EscalationCheck -->|"🚨 Escalation = TRUE"| Path4_1["4.1 Regular Medical Prompts<br/>+ Triage"]:::prompt
42
+ Path4_1 --> AfterTriage
43
+
44
+ AfterTriage{"After Triage:<br/>Is lifestyle still relevant?"}:::decision
45
+ AfterTriage -->|"YES"| SetCheckIn["Set next check-in time<br/>OR activate immediately"]
46
+ AfterTriage -->|"NO"| EndMedical["Continue Medical Flow"]
47
+
48
+ SetCheckIn -.->|"Schedule next<br/>lifestyle session"| Trigger2
49
+ SetCheckIn -->|"Immediate"| LifestylePromptAfterTriage[["💚 LIFESTYLE PROMPT"]]:::lifestyle
50
+
51
+
52
+ %% Path 4.2: Escalation = FALSE + Lifestyle = TRUE
53
+ EscalationCheck -->|"✅ No Escalation +<br/>Lifestyle Trigger"| Path4_2["4.2 Direct to Lifestyle"]
54
+ Path4_2 --> LifestylePromptDirect3[["💚 LIFESTYLE PROMPT"]]:::lifestyle
55
+
56
+ %% Lifestyle Prompt Logic
57
+ LifestylePromptDirect1 --> ProfileCheck
58
+ LifestylePromptDirect2 --> ProfileCheck
59
+ LifestylePromptDirect3 --> ProfileCheck
60
+ LifestylePromptAfterTriage --> ProfileCheck
61
+
62
+ ProfileCheck{"Patient Profile<br/>Exists?"}:::decision
63
+
64
+ ProfileCheck -->|"❌ NO Profile"| GatherInfo["📋 GATHER INFORMATION<br/>• Limitations<br/>• Preferences<br/>• Goals<br/>• Medical conditions"]:::prompt
65
+ ProfileCheck -->|"✅ HAS Profile"| LifestyleCoaching["💚 LIFESTYLE COACHING<br/>Based on existing profile"]:::lifestyle
66
+
67
+ GatherInfo --> CreateProfile["Create Initial<br/>Patient Profile"]
68
+ CreateProfile --> LifestyleCoaching
69
+
70
+ LifestyleCoaching --> UpdateProfile["🔄 Update Profile<br/>with session data"]
71
+ UpdateProfile --> SessionEnd["Session Complete"]
72
+
diagram/lifestyle-activation-logic.txt ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flowchart TD
2
+ %% Стилізація
3
+ classDef trigger fill:#e8f5e9,stroke:#4caf50,stroke-width:3px
4
+ classDef classifier fill:#fff3e0,stroke:#ff9800,stroke-width:2px
5
+ classDef prompt fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
6
+ classDef decision fill:#ffebee,stroke:#f44336,stroke-width:2px
7
+ classDef lifestyle fill:#f3e5f5,stroke:#9c27b0,stroke-width:3px
8
+
9
+ %% Три способи активації
10
+ Start([Start])
11
+ Start --> CheckTriggers
12
+
13
+ CheckTriggers{Checking triggers}
14
+
15
+ %% ТРИГЕР 1: Scheduled
16
+ CheckTriggers -->|"📅 Scheduled"| Trigger1["1️⃣ MRE Scheduled Basis<br/>(e.g., once per week)"]:::trigger
17
+ Trigger1 --> LifestylePromptDirect1[["💚 LIFESTYLE PROMPT"]]:::lifestyle
18
+
19
+ %% ТРИГЕР 2: Follow-up
20
+ CheckTriggers -->|"🔄 Follow-up"| Trigger2["2️⃣ LLM requested follow-up<br/>in previous session"]:::trigger
21
+ Trigger2 --> LifestylePromptDirect2[["💚 LIFESTYLE PROMPT"]]:::lifestyle
22
+
23
+ %% ТРИГЕР 3: Patient Initiated
24
+ CheckTriggers -->|"💬 Message"| Trigger3["3️⃣ Patient message"]:::trigger
25
+
26
+ %% Детальна логіка для patient-initiated
27
+ Trigger3 --> Step3_1["3.1 Check Lifestyle Trigger<br/>(keywords, patterns)"]:::classifier
28
+
29
+ Step3_1 -->|"NO lifestyle markers"| RegularFlow["Regular Medical Flow"]
30
+ Step3_1 -->|"YES lifestyle markers"| Step3_2
31
+
32
+ Step3_2["3.2 Gemini Classifier<br/>(type of MRE/CE message)"]:::classifier
33
+ Step3_2 --> Step3_3
34
+
35
+ Step3_3["3.3 FIRST PROMPT<br/>Generate: Suggested message + Escalation flag"]:::prompt
36
+ Step3_3 --> EscalationCheck
37
+
38
+ EscalationCheck{"3.4 Check Escalation Flag"}:::decision
39
+
40
+ %% Path 4.1: Escalation = TRUE
41
+ EscalationCheck -->|"🚨 Escalation = TRUE"| Path4_1["4.1 Regular Medical Prompts<br/>+ Triage"]:::prompt
42
+ Path4_1 --> AfterTriage
43
+
44
+ AfterTriage{"After Triage:<br/>Is lifestyle still relevant?"}:::decision
45
+ AfterTriage -->|"YES"| SetCheckIn["Set next check-in time<br/>OR activate immediately"]
46
+ AfterTriage -->|"NO"| EndMedical["Continue Medical Flow"]
47
+
48
+ SetCheckIn -.->|"Schedule next<br/>lifestyle session"| Trigger2
49
+ SetCheckIn -->|"Immediate"| LifestylePromptAfterTriage[["💚 LIFESTYLE PROMPT"]]:::lifestyle
50
+
51
+
52
+ %% Path 4.2: Escalation = FALSE + Lifestyle = TRUE
53
+ EscalationCheck -->|"✅ No Escalation +<br/>Lifestyle Trigger"| Path4_2["4.2 Direct to Lifestyle"]
54
+ Path4_2 --> LifestylePromptDirect3[["💚 LIFESTYLE PROMPT"]]:::lifestyle
55
+
56
+ %% Lifestyle Prompt Logic
57
+ LifestylePromptDirect1 --> ProfileCheck
58
+ LifestylePromptDirect2 --> ProfileCheck
59
+ LifestylePromptDirect3 --> ProfileCheck
60
+ LifestylePromptAfterTriage --> ProfileCheck
61
+
62
+ ProfileCheck{"Patient Profile<br/>Exists?"}:::decision
63
+
64
+ ProfileCheck -->|"❌ NO Profile"| GatherInfo["📋 GATHER INFORMATION<br/>• Limitations<br/>• Preferences<br/>• Goals<br/>• Medical conditions"]:::prompt
65
+ ProfileCheck -->|"✅ HAS Profile"| LifestyleCoaching["💚 LIFESTYLE COACHING<br/>Based on existing profile"]:::lifestyle
66
+
67
+ GatherInfo --> CreateProfile["Create Initial<br/>Patient Profile"]
68
+ CreateProfile --> LifestyleCoaching
69
+
70
+ LifestyleCoaching --> UpdateProfile["🔄 Update Profile<br/>with session data"]
71
+ UpdateProfile --> SessionEnd["Session Complete"]
72
+
diagram/lifestyle-architecture.mermaid ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flowchart TD
2
+ %% Стилізація
3
+ classDef patient fill:#e8f5e9,stroke:#4caf50,stroke-width:3px
4
+ classDef existing fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
5
+ classDef new fill:#fff3e0,stroke:#ff9800,stroke-width:2px
6
+ classDef data fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
7
+
8
+ %% Вхідні компоненти
9
+ Patient[("👤 ПАЦІЄНТ")]:::patient
10
+ DB[("🗄️ БАЗА ДАНИХ<br/>Clinical Background<br/>Історія чатів<br/>Patient Profile")]:::data
11
+
12
+ %% Детектор режиму
13
+ Detector{{"🔍 LLM-ДЕТЕКТОР<br/>Аналіз контексту<br/><b>[НОВИЙ]</b>"}}:::new
14
+
15
+ Patient -->|Повідомлення| Detector
16
+ DB -->|Контекст| Detector
17
+
18
+ %% Розгалуження
19
+ Detector -->|URGENT/REGULAR| MedicalFlow
20
+ Detector -->|LIFESTYLE| LifestyleFlow
21
+
22
+ %% Медичний потік (існуючий)
23
+ subgraph MedicalFlow["⚕️ МЕДИЧНИЙ ПОТІК [ІСНУЮЧИЙ]"]
24
+ direction LR
25
+ MRE["MRE<br/>Rule Engine"]:::existing
26
+ Assistant["LLM-Асистент<br/>Валідатор"]:::existing
27
+ MRE --> Assistant
28
+ end
29
+
30
+ %% Lifestyle потік (новий)
31
+ subgraph LifestyleFlow["💚 LIFESTYLE ПОТІК [НОВИЙ]"]
32
+ direction LR
33
+ LifestyleLLM["Lifestyle LLM<br/>Коучинг"]:::new
34
+ ProfileUpdate["Оновлення<br/>профілю"]:::new
35
+ LifestyleLLM --> ProfileUpdate
36
+ end
37
+
38
+ %% Відповідь
39
+ MedicalFlow -->|Медична відповідь| CE
40
+ LifestyleFlow -->|Коучинг відповідь| CE
41
+ CE["📱 CE/Пацієнт"]:::patient
42
+
43
+ %% Зворотній зв'язок
44
+ ProfileUpdate -.->|Оновлення| DB
45
+ Assistant -.->|Логування| DB
diagram/profile-lifecycle.mermaid ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flowchart TD
2
+ Start([Новий пацієнт])
3
+ Start --> InitialData
4
+
5
+ %% ЕТАП 1: ІНІЦІАЛІЗАЦІЯ
6
+ subgraph Init["🚀 ЕТАП 1: ІНІЦІАЛІЗАЦІЯ ПРОФІЛЮ"]
7
+ InitialData["📊 Збір базових даних<br/>• Clinical Background<br/>• Медикаменти<br/>• Діагнози"]
8
+ InitialData --> FirstSession
9
+
10
+ FirstSession["💬 Перша ознайомча сесія<br/>• Пояснення мети<br/>• Оцінка готовності<br/>• Базові питання"]
11
+ FirstSession --> Assessment
12
+
13
+ Assessment["📋 Детальна оцінка<br/>• Фізичні можливості<br/>• Харчові звички<br/>• Психосоціальні фактори<br/>• Мотивація"]
14
+ end
15
+
16
+ Assessment --> CreateProfile
17
+
18
+ %% ЕТАП 2: СТВОРЕННЯ
19
+ CreateProfile["🔨 Формування профілю v1.0<br/>• Автоматичне заповнення з медичних даних<br/>• Додавання відповідей з оцінки<br/>• Встановлення безпечних defaults"]
20
+
21
+ CreateProfile --> Validation
22
+
23
+ %% ЕТАП 3: ВАЛІДАЦІЯ
24
+ subgraph Valid["✅ ВАЛІДАЦІЯ ТА БЕЗПЕКА"]
25
+ Validation{Перевірка на<br/>протиріччя}
26
+ Validation -->|Знайдено| Clarify["🔍 Уточнення з пацієнтом<br/>або медичною командою"]
27
+ Validation -->|OK| Safety
28
+ Clarify --> Safety
29
+
30
+ Safety["🛡️ Перевірка безпеки<br/>• Red flags<br/>• Обмеження<br/>• Протипоказання"]
31
+ end
32
+
33
+ Safety --> Active
34
+
35
+ %% ЕТАП 4: АКТИВНЕ ВИКОРИСТАННЯ
36
+ subgraph Usage["💚 АКТИВНЕ ВИКОРИСТАННЯ"]
37
+ Active["📱 Профіль активний"]
38
+ Active --> Session["Lifestyle сесія"]
39
+ Session --> Track["📈 Трекінг<br/>• Виконання плану<br/>• Симптоми<br/>• Прогрес"]
40
+ Track --> Update{Потрібне<br/>оновлення?}
41
+ end
42
+
43
+ %% ЕТАП 5: ОНОВЛЕННЯ
44
+ Update -->|Так| UpdateFlow
45
+ Update -->|Ні| Session
46
+
47
+ subgraph UpdateFlow["🔄 ОНОВЛЕННЯ ПРОФІЛЮ"]
48
+ UpdateType{Тип оновлення}
49
+ UpdateType -->|Прогрес| ProgressUpdate["📊 Оновлення прогресу<br/>• Нові досягнення<br/>• Зміна можливостей<br/>• Коригування цілей"]
50
+ UpdateType -->|Медичне| MedicalUpdate["⚕️ Медичні зміни<br/>• Нові діагнози<br/>• Зміна ліків<br/>• Нові обмеження"]
51
+ UpdateType -->|Поведінкове| BehaviorUpdate["🧠 Зміни поведінки<br/>• Нові бар'єри<br/>• Зміна мотивації<br/>• Нові преференції"]
52
+
53
+ ProgressUpdate --> Version
54
+ MedicalUpdate --> Version
55
+ BehaviorUpdate --> Version
56
+
57
+ Version["📝 Створення нової версії<br/>• Збереження історії<br/>• Логування змін<br/>• Timestamp"]
58
+ end
59
+
60
+ Version --> Safety
61
+
62
+ %% Додаткові процеси
63
+ subgraph Review["🔍 ПЕРІОДИЧНИЙ REVIEW"]
64
+ Monthly["📅 Щомісячний аналіз<br/>• Ефективність підходу<br/>• Adherence rate<br/>• Необхідність змін"]
65
+ Quarterly["📊 Квартальний звіт<br/>• Загальний прогрес<br/>• Досягнення цілей<br/>• Рекомендації"]
66
+ end
67
+
68
+ Active -.->|Періодично| Review
69
+ Review -.-> UpdateFlow
70
+
71
+ style Init fill:#e8f5e9
72
+ style Valid fill:#fff3e0
73
+ style Usage fill:#e3f2fd
74
+ style UpdateFlow fill:#fce4ec
75
+ style Review fill:#f3e5f5
diagram/system-sequence.mermaid ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sequenceDiagram
2
+ participant P as 👤 Пацієнт
3
+ participant D as 🔍 LLM-Детектор
4
+ participant DB as 🗄️ База даних
5
+ participant MRE as ⚕️ MRE
6
+ participant A as ✅ Асистент
7
+ participant L as 💚 Lifestyle LLM
8
+ participant CE as 📱 CE (Interface)
9
+
10
+ Note over P,CE: Сценарій 1: Медичне питання
11
+ P->>D: "Вчора був тиск 150/95"
12
+ D->>DB: Запит контексту
13
+ DB->>D: Clinical background + історія
14
+ D->>D: Аналіз: REGULAR
15
+ D->>MRE: Передача повідомлення
16
+ MRE->>A: Медична відповідь
17
+ A->>A: Валідація
18
+ A->>CE: Підтверджена відповідь
19
+ CE->>P: "Це підвищений тиск..."
20
+
21
+ Note over P,CE: Сценарій 2: Lifestyle запит
22
+ P->>D: "Хочу почати ходити щодня"
23
+ D->>DB: Запит контексту + lifestyle профіль
24
+ DB->>D: Дані пацієнта + обмеження
25
+ D->>D: Аналіз: LIFESTYLE_NEEDED
26
+ D->>L: Активація lifestyle режиму
27
+ L->>DB: Запит Patient Profile
28
+ DB->>L: Поточний профіль
29
+ L->>L: Генерація плану
30
+ L->>CE: Коучинг відповідь
31
+ CE->>P: "Чудово! Давайте почнемо з 15 хв..."
32
+ L->>DB: Оновлення профілю
33
+
34
+ Note over P,CE: Сценарій 3: Змішаний контекст
35
+ P->>D: "Втомлююсь, але хочу бути активнішим"
36
+ D->>DB: Запит повного контексту
37
+ DB->>D: Медичні дані + історія
38
+ D->>D: Аналіз: MIXED
39
+ D->>MRE: Спочатку медична перевірка
40
+ MRE->>A: Оцінка симптому
41
+ A->>D: Симптом не критичний
42
+ D->>L: Можна перейти до lifestyle
43
+ L->>CE: "Втома може бути від низької активності..."
44
+ CE->>P: Комбінована відповідь
lifestyle_profile.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "patient_name": "Serhii",
3
+ "patient_age": "52",
4
+ "conditions": [
5
+ "arrhythmia",
6
+ "hypertension"
7
+ ],
8
+ "primary_goal": "Improve exercise tolerance safely to help control BP",
9
+ "exercise_preferences": [
10
+ "walking outdoors",
11
+ "light stretching"
12
+ ],
13
+ "exercise_limitations": [
14
+ "avoid vigorous or high-impact activity due to arrhythmia"
15
+ ],
16
+ "dietary_notes": [
17
+ "low sodium",
18
+ "moderate carb intake"
19
+ ],
20
+ "personal_preferences": [
21
+ "prefers gradual changes",
22
+ "wants to feel in control of pace"
23
+ ],
24
+ "journey_summary": "Patient expressed interest in increasing physical activity. Started with 15-min walks 3x/week and tolerated well.",
25
+ "last_session_summary": "Encouraged to continue 15-min walks; agreed to assess symptoms before progressing.",
26
+ "next_check_in": "not set"
27
+ }
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core dependencies for Lifestyle Journey MVP
2
+ gradio>=4.0.0
3
+ python-dotenv>=1.0.0
4
+ google-genai>=0.5.0
5
+
6
+ # Data handling
7
+ typing-extensions>=4.5.0
8
+
9
+ # For HuggingFace Spaces compatibility
10
+ huggingface-hub>=0.16.0