File size: 7,036 Bytes
eeb0f9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import base64
from utils.helpers import chat_logic
import uuid
from pathlib import Path
from auth.auth import (
    register_user, login_user, logout_user, load_history, save_message, clear_history
)
from health_data import HealthContext, HealthDataStore
from health_analysis import HealthAnalyzer
from fitness_tracking import FitnessTracker
from utils.speech_recognition import transcribe_speech
import gradio as gr
import logging
import threading
import time

logger = logging.getLogger(__name__)

# Dictionary to store user IDs for each agent type
user_sessions = {}
data_store = HealthDataStore()

# Global state for voice recording
voice_recording_state = {
    "is_recording": False,
    "lock": threading.Lock()
}

# Global state for voice recording
voice_recording_state = {
    "is_recording": False,
    "lock": threading.Lock()
}


def setup_handlers(message, chatbot, submit_btn, clear_btn, session, audio_input=None):
    """Setup event handlers for hybrid Gradio + ModelScope chatbot"""

    def agent_chat_handler(user_input, chatbot_value):
        username = session.value.get("user")
        user_id = username

        # Nếu chưa có dữ liệu, khởi tạo list messages
        if not chatbot_value:
            chatbot_value = []

        # Lưu history cũ (không có user message mới)
        old_history = chatbot_value.copy()

        # Thêm user message dưới dạng ChatbotDataMessage để hiển thị
        from modelscope_studio.components.pro.chatbot import ChatbotDataMessage

        user_message = ChatbotDataMessage(
            role="user",
            content=user_input
        )
        chatbot_value.append(user_message)

        # Hiện bot đang xử lý
        pending_message = ChatbotDataMessage(
            role="assistant",
            content="",
            loading=True,
            status="pending"
        )
        chatbot_value.append(pending_message)
        yield gr.update(value=""), gr.update(value=chatbot_value)

        # Gọi logic backend với history cũ (không có user message mới)
        try:
            # chat_logic sẽ tự thêm user message vào history
            _, updated_chat_history = chat_logic(
                user_input, old_history, user_id=user_id)
            time.sleep(0.2)

            # Cập nhật toàn bộ chatbot_value với kết quả mới
            if updated_chat_history and len(updated_chat_history) > 0:
                last_message = updated_chat_history[-1]

                # Cập nhật pending message cuối cùng thành response
                chatbot_value[-1] = last_message

            if username:
                save_message(username, user_input)
                if hasattr(last_message, 'content') and last_message.role == 'assistant':
                    save_message(username, last_message.content)

        except Exception as e:
            # Xử lý lỗi bằng cách cập nhật tin nhắn cuối
            if chatbot_value and len(chatbot_value) > 0:
                from modelscope_studio.components.pro.chatbot import ChatbotDataMessage
                error_message = ChatbotDataMessage(
                    role="assistant",
                    content=f"❌ Lỗi xử lý: {str(e)}"
                )
                chatbot_value[-1] = error_message

        yield gr.update(value=""), gr.update(value=chatbot_value)

    def welcome_prompt_select(chatbot_value, e: gr.EventData):
        prompt_text = e._data["payload"][0]["value"]["description"]
        return gr.update(value=prompt_text)

    # Bind submit button & textbox event
    message.submit(agent_chat_handler, [message, chatbot], [message, chatbot])
    submit_btn.click(agent_chat_handler, [
                     message, chatbot], [message, chatbot])
    chatbot.welcome_prompt_select(fn=welcome_prompt_select,
                                  inputs=[chatbot],
                                  outputs=[message])

    # Clear chat
    def clear_chat():
        username = session.value.get("user")
        if username:
            clear_history(username)
        # Return sample messages to demonstrate features
        from utils.helpers import create_sample_chatbot_messages
        return gr.update(value=create_sample_chatbot_messages())

    clear_btn.click(clear_chat, None, chatbot)

    # Speech input handler (nếu có audio)
    if audio_input:
        def handle_speech_input(audio_filepath):
            if not audio_filepath:
                return gr.update()

            try:
                time.sleep(0.2)
                transcribed_text = transcribe_speech(audio_filepath)
                current_text = message.value or ""
                updated_text = (current_text + " " + transcribed_text).strip()
                return gr.update(value=updated_text), gr.update(value=None)
            except Exception as e:
                print(f"Speech transcription error: {str(e)}")
                return gr.update(), gr.update(value=None)

        audio_input.change(handle_speech_input,
                           inputs=[audio_input],
                           outputs=[message, audio_input])


def handle_load_history(u):
    history = load_history(u)
    # If no history exists, return sample messages to demonstrate features
    if not history:
        from utils.helpers import create_sample_chatbot_messages
        return create_sample_chatbot_messages()
    return history


def handle_login(u, p, state):
    success, msg = login_user(u, p)
    if success:
        state.value["user"] = u
        return True, msg, u
    return False, msg, []


def handle_register(u, p, state):
    success, msg = register_user(u, p)
    return success, msg


def handle_logout(state):
    logout_user(state)
    return ""


def create_health_dashboard(user_id):
    """Create health dashboard with insights from health context"""
    if not user_id:
        return {
            'health_score': 0,
            'risks': [],
            'fitness_metrics': {},
            'health_history': []
        }

    try:
        health_context = HealthContext(user_id, data_store)
        analyzer = HealthAnalyzer(health_context)
        tracker = FitnessTracker(health_context)

        # Calculate health metrics
        health_score = analyzer.calculate_health_score()
        risks = analyzer.identify_health_risks()
        fitness_metrics = tracker.calculate_progress_metrics()

        # Get health history
        health_history = health_context.get_health_history()

        return {
            'health_score': health_score,
            'risks': risks,
            'fitness_metrics': fitness_metrics,
            'health_history': health_history,
            'profile': health_context.get_user_profile().to_dict()
        }
    except Exception as e:
        print(f"Error creating health dashboard: {e}")
        return {
            'health_score': 0,
            'risks': [],
            'fitness_metrics': {},
            'health_history': [],
            'error': str(e)
        }