|
1 | 1 | import streamlit as st
|
2 |
| -from core.db import get_messages, add_message |
3 |
| -from core.utils import get_current_time, get_ai_response |
| 2 | +import streamlit.components.v1 as components |
| 3 | +from datetime import datetime |
| 4 | +from core.utils import get_current_time, get_ai_response, save_conversations |
| 5 | +import requests |
4 | 6 |
|
5 |
| -def render_chat_interface(model): |
6 |
| - chat_id = st.session_state.get("active_chat_id") |
7 |
| - if not chat_id: |
8 |
| - st.info("Start a new chat to begin.") |
9 |
| - return |
| 7 | +# Inject JS to get user's local time zone |
| 8 | +def set_user_time_in_session(): |
| 9 | + if "user_time_offset" not in st.session_state: |
| 10 | + components.html(""" |
| 11 | + <script> |
| 12 | + const offset = new Date().getTimezoneOffset(); |
| 13 | + const time = new Date().toLocaleString(); |
| 14 | + const data = {offset: offset, time: time}; |
| 15 | + window.parent.postMessage({type: 'USER_TIME', data: data}, '*'); |
| 16 | + </script> |
| 17 | + """, height=0) |
10 | 18 |
|
11 |
| - messages = get_messages(chat_id) |
12 |
| - if not messages: |
13 | 19 | st.markdown("""
|
14 |
| - <div class="welcome-message"> |
15 |
| - <strong>Hello! I'm TalkHeal, your mental health companion</strong><br> |
16 |
| - How are you feeling today? You can write it down below or for a fresh start click on "➕ New Chat" 😊 |
17 |
| - </div> |
| 20 | + <script> |
| 21 | + window.addEventListener("message", (event) => { |
| 22 | + if (event.data.type === "USER_TIME") { |
| 23 | + const payload = JSON.stringify(event.data.data); |
| 24 | + fetch("/", { |
| 25 | + method: "POST", |
| 26 | + headers: {"Content-Type": "application/json"}, |
| 27 | + body: payload |
| 28 | + }).then(() => location.reload()); |
| 29 | + } |
| 30 | + }); |
| 31 | + </script> |
18 | 32 | """, unsafe_allow_html=True)
|
19 | 33 |
|
20 |
| - for msg in messages: |
21 |
| - if msg["sender"] == "user": |
| 34 | +set_user_time_in_session() |
| 35 | + |
| 36 | +# Display chat messages |
| 37 | +def render_chat_interface(): |
| 38 | + if st.session_state.active_conversation >= 0: |
| 39 | + active_convo = st.session_state.conversations[st.session_state.active_conversation] |
| 40 | + |
| 41 | + if not active_convo["messages"]: |
22 | 42 | st.markdown(f"""
|
23 |
| - <div class="user-message"> |
24 |
| - {msg["message"]} |
25 |
| - <div class="message-time">{msg["timestamp"]}</div> |
| 43 | + <div class="welcome-message"> |
| 44 | + <strong>Hello! I'm TalkHeal, your mental health companion 🤗</strong><br> |
| 45 | + How are you feeling today? You can write below or start a new topic. |
| 46 | + <div class="message-time">{get_current_time()}</div> |
26 | 47 | </div>
|
27 | 48 | """, unsafe_allow_html=True)
|
28 |
| - else: |
| 49 | + |
| 50 | + for msg in active_convo["messages"]: |
| 51 | + css_class = "user-message" if msg["sender"] == "user" else "bot-message" |
29 | 52 | st.markdown(f"""
|
30 |
| - <div class="bot-message"> |
| 53 | + <div class="{css_class}"> |
31 | 54 | {msg["message"]}
|
32 |
| - <div class="message-time">{msg["timestamp"]}</div> |
| 55 | + <div class="message-time">{msg["time"]}</div> |
33 | 56 | </div>
|
34 | 57 | """, unsafe_allow_html=True)
|
35 | 58 |
|
| 59 | +# Handle chat input and generate AI response |
| 60 | +def handle_chat_input(model, system_prompt): |
| 61 | + if "pre_filled_chat_input" not in st.session_state: |
| 62 | + st.session_state.pre_filled_chat_input = "" |
| 63 | + initial_value = st.session_state.pre_filled_chat_input |
| 64 | + st.session_state.pre_filled_chat_input = "" |
| 65 | + |
36 | 66 | with st.form(key="chat_form", clear_on_submit=True):
|
37 |
| - user_input = st.text_input("Share your thoughts...", key="message_input", label_visibility="collapsed") |
38 |
| - send_pressed = st.form_submit_button("Send") |
39 |
| - if send_pressed and user_input.strip(): |
40 |
| - add_message(chat_id, "user", user_input.strip()) |
41 |
| - with st.spinner("TalkHeal is thinking..."): |
42 |
| - context = "\n".join([f"{m['sender'].capitalize()}: {m['message']}" for m in get_messages(chat_id)]) |
43 |
| - prompt = context + f"\nUser: {user_input.strip()}\nBot:" |
44 |
| - ai_response = get_ai_response(prompt, model) |
45 |
| - add_message(chat_id, "bot", ai_response) |
46 |
| - st.rerun() |
| 67 | + col1, col2 = st.columns([5, 1]) |
| 68 | + with col1: |
| 69 | + user_input = st.text_input( |
| 70 | + "Share your thoughts...", |
| 71 | + key="message_input", |
| 72 | + label_visibility="collapsed", |
| 73 | + placeholder="Type your message here...", |
| 74 | + value=initial_value |
| 75 | + ) |
| 76 | + with col2: |
| 77 | + send_pressed = st.form_submit_button("Send", use_container_width=True) |
| 78 | + |
| 79 | + if (send_pressed or st.session_state.get("send_chat_message", False)) and user_input.strip(): |
| 80 | + if 'send_chat_message' in st.session_state: |
| 81 | + st.session_state.send_chat_message = False |
| 82 | + |
| 83 | + if st.session_state.active_conversation >= 0: |
| 84 | + current_time = get_current_time() |
| 85 | + active_convo = st.session_state.conversations[st.session_state.active_conversation] |
| 86 | + |
| 87 | + # Save user message |
| 88 | + active_convo["messages"].append({ |
| 89 | + "sender": "user", |
| 90 | + "message": user_input.strip(), |
| 91 | + "time": current_time |
| 92 | + }) |
| 93 | + |
| 94 | + # Set title if it's the first message |
| 95 | + if len(active_convo["messages"]) == 1: |
| 96 | + title = user_input[:30] + "..." if len(user_input) > 30 else user_input |
| 97 | + active_convo["title"] = title |
| 98 | + |
| 99 | + save_conversations(st.session_state.conversations) |
| 100 | + |
| 101 | + # Format memory |
| 102 | + def format_memory(convo_history, max_turns=10): |
| 103 | + context = "" |
| 104 | + for msg in convo_history[-max_turns*2:]: # user + bot per turn |
| 105 | + sender = "User" if msg["sender"] == "user" else "Bot" |
| 106 | + context += f"{sender}: {msg['message']}\n" |
| 107 | + return context |
| 108 | + |
| 109 | + try: |
| 110 | + with st.spinner("TalkHeal is thinking..."): |
| 111 | + memory = format_memory(active_convo["messages"]) |
| 112 | + prompt = f"{system_prompt}\n\n{memory}\nUser: {user_input.strip()}\nBot:" |
| 113 | + ai_response = get_ai_response(prompt, model) |
| 114 | + |
| 115 | + active_convo["messages"].append({ |
| 116 | + "sender": "bot", |
| 117 | + "message": ai_response, |
| 118 | + "time": get_current_time() |
| 119 | + }) |
| 120 | + |
| 121 | + except ValueError as e: |
| 122 | + st.error("I'm having trouble understanding your message. Could you please rephrase it?") |
| 123 | + active_convo["messages"].append({ |
| 124 | + "sender": "bot", |
| 125 | + "message": "I'm having trouble understanding your message. Could you please rephrase it?", |
| 126 | + "time": get_current_time() |
| 127 | + }) |
| 128 | + except requests.RequestException as e: |
| 129 | + st.error("Network connection issue. Please check your internet connection.") |
| 130 | + active_convo["messages"].append({ |
| 131 | + "sender": "bot", |
| 132 | + "message": "I'm having trouble connecting to my services. Please check your internet connection and try again.", |
| 133 | + "time": get_current_time() |
| 134 | + }) |
| 135 | + except Exception as e: |
| 136 | + st.error(f"An unexpected error occurred. Please try again.") |
| 137 | + active_convo["messages"].append({ |
| 138 | + "sender": "bot", |
| 139 | + "message": "I'm having trouble responding right now. Please try again in a moment.", |
| 140 | + "time": get_current_time() |
| 141 | + }) |
47 | 142 |
|
| 143 | + save_conversations(st.session_state.conversations) |
| 144 | + st.rerun() |
0 commit comments