File size: 4,042 Bytes
8dc422f
1ee7cae
8dc422f
 
1ee7cae
8dc422f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import streamlit as st
import time
from src.rag_service import RAGService

# --- KONFIGURASI HALAMAN ---
st.set_page_config(
    page_title="HealthBot AI - Skripsi",
    page_icon="πŸ₯",
    layout="centered"
)

# --- CSS SEDERHANA UNTUK MEMPERCANTIK ---
st.markdown("""
    <style>
    .chat-message {
        padding: 1.5rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex
    }
    .chat-message.user {
        background-color: #e6f3ff;
    }
    .chat-message.bot {
        background-color: #f0f2f6;
    }
    .source-box {
        font-size: 0.8em; color: #666; margin-top: 10px; padding: 10px; 
        background-color: #fff; border: 1px solid #ddd; border-radius: 5px;
    }
    </style>
""", unsafe_allow_html=True)

# --- HEADER ---
st.title("πŸ₯ Asisten Kesehatan AI (RAG)")
st.caption(f"πŸš€ Skripsi Prototype | Powered by {os.getenv('ACTIVE_MODEL').upper()} & Alodokter Data")

with st.expander("ℹ️  Tentang Sistem Ini"):
    st.markdown("""
    Sistem ini menggunakan **Retrieval-Augmented Generation (RAG)**.
    1. Pertanyaan Anda diubah menjadi vektor.
    2. Sistem mencari 7 artikel paling relevan di database **Alodokter**.
    3. **Llama-3 (Groq)** menjawab berdasarkan artikel tersebut.
    
    *Disclaimer: Bukan pengganti saran medis profesional.*
    """)

# --- INISIALISASI SESSION STATE ---
if "messages" not in st.session_state:
    st.session_state.messages = []

# --- FUNGSI LOAD RAG DENGAN CACHE ---
@st.cache_resource(show_spinner=False)
def load_rag_engine():
    """
    Fungsi ini hanya akan jalan 1 KALI saja saat server pertama nyala.
    Selanjutnya, Streamlit akan mengambil data dari memori (RAM) instan.
    """
    return RAGService()

# Inisialisasi RAG Engine (Hanya sekali jalan agar cepat)
if "rag" not in st.session_state:
    with st.spinner("Sedang memuat perpustakaan medis..."):
        try:
            st.session_state.rag = load_rag_engine()
            st.success("βœ… Sistem Siap!")
            time.sleep(1) # Biar user sempat lihat pesan sukses
            st.rerun()    # Refresh halaman untuk hilangkan pesan loading
        except Exception as e:
            st.error(f"❌ Gagal memuat RAG: {e}")
            st.stop()

# --- TAMPILKAN RIWAYAT CHAT ---
for msg in st.session_state.messages:
    with st.chat_message(msg["role"]):
        st.markdown(msg["content"])

# --- INPUT & LOGIKA CHAT ---
if prompt := st.chat_input("Contoh: Apa obat sakit kepala dan berapa dosisnya?"):
    
    # 1. Tampilkan Pesan User
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.markdown(prompt)

    # 2. Proses Jawaban AI
    with st.chat_message("assistant"):
        message_placeholder = st.empty()
        status_placeholder = st.empty()
        
        status_placeholder.markdown("πŸ” *Mencari referensi di database...*")
        
        try:
            # Panggil Fungsi RAG
            start_time = time.time()
            answer, sources = st.session_state.rag.ask(prompt)
            end_time = time.time()
            duration = end_time - start_time
            
            # Hilangkan status loading
            status_placeholder.empty()
            
            # Format Output
            full_response = answer
            
            # Tambahkan kotak sumber yang cantik
            if sources:
                sources_md = "\n\n**πŸ“š Sumber Referensi:**\n"
                for s in sources:
                    sources_md += f"- [{s}]({s})\n"
                full_response += sources_md
            
            full_response += f"\n\n_⏱️ Waktu proses: {duration:.2f} detik_"

            # Tampilkan Jawaban
            message_placeholder.markdown(full_response)
            
            # Simpan ke Session
            st.session_state.messages.append({"role": "assistant", "content": full_response})
            
        except Exception as e:
            status_placeholder.empty()
            message_placeholder.error(f"Terjadi kesalahan sistem: {str(e)}")