Spaces:
Running
Running
| import streamlit as st | |
| import requests | |
| import json | |
| import os | |
| # --- μ€μ λ° λ³΄μ --- | |
| # νκ²½λ³μ λ―Έμ€μ μ λΉλ°λ²νΈ 0000 | |
| st.set_page_config(page_title="νμλ νμΉ μ±λ΄", page_icon="π¦") | |
| ACCESS_PASSWORD = os.getenv("APP_PASSWORD", "0000") | |
| if "authenticated" not in st.session_state: | |
| st.session_state.authenticated = False | |
| def check_password(): | |
| if st.session_state.password_input == ACCESS_PASSWORD: | |
| st.session_state.authenticated = True | |
| del st.session_state.password_input | |
| else: | |
| st.error("λΉλ°λ²νΈκ° νλ Έμ΅λλ€.") | |
| if not st.session_state.authenticated: | |
| st.title("π μ κ·Ό μ ν") | |
| st.text_input("λΉλ°λ²νΈλ₯Ό μ λ ₯νμΈμ", type="password", key="password_input", on_change=check_password) | |
| st.stop() | |
| # --- UI ꡬν --- | |
| st.title("π¦ νμλνκ΅ νμΉ μ±λ΄ (RAG)") | |
| st.caption("GPT-5-mini & Real-time Hybrid Search & Reranking") | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = [] | |
| # νμ€ν 리 νμ | |
| for message in st.session_state.messages: | |
| with st.chat_message(message["role"]): | |
| st.markdown(message["content"]) | |
| if message.get("docs"): | |
| with st.expander("μ°Έκ³ λ¬Έμ (Evidence)"): | |
| for idx, doc in enumerate(message["docs"]): | |
| st.text(f"[{idx+1}] {doc['source']}: {doc['content']}") | |
| # μ λ ₯ μ²λ¦¬ | |
| if prompt := st.chat_input("μ§λ¬Έμ μ λ ₯νμΈμ..."): | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| with st.chat_message("user"): | |
| st.markdown(prompt) | |
| with st.chat_message("assistant"): | |
| # μ€μκ° μ§ν μν©μ 보μ¬μ€ 컨ν μ΄λ (Gemini μ€νμΌ) | |
| status_container = st.status("π μ²λ¦¬ μ€...", expanded=True) | |
| answer_placeholder = st.empty() | |
| full_answer = "" | |
| received_docs = [] | |
| try: | |
| # stream=Trueλ‘ μμ²νμ¬ ν μ€μ© λ°μ | |
| response = requests.post( | |
| "http://localhost:8000/chat", # λ°°ν¬ νκ²½μμλ localhost μ¬μ© κ°λ₯ (Docker λ΄λΆ) | |
| json={"query": prompt, "history": []}, | |
| stream=True | |
| ) | |
| for line in response.iter_lines(): | |
| if line: | |
| try: | |
| data = json.loads(line.decode('utf-8')) | |
| msg_type = data["type"] | |
| content = data["content"] | |
| if msg_type == "log": | |
| # λ‘κ·Έλ Status 컨ν μ΄λμ κΈ°λ‘ (νλ¦° κΈμ¨ ν¨κ³Ό λμ λ¨κ³λ³ νμ) | |
| status_container.write(content) | |
| status_container.update(label=content) # νμ¬ λ¨κ³ μ λͺ© μ λ°μ΄νΈ | |
| elif msg_type == "answer": | |
| # λ΅λ³μ μ€μκ° νμ΄ν ν¨κ³Ό | |
| full_answer += content | |
| answer_placeholder.markdown(full_answer + "β") | |
| elif msg_type == "docs": | |
| received_docs = content | |
| except json.JSONDecodeError: | |
| continue | |
| # μλ£ ν μ²λ¦¬ | |
| answer_placeholder.markdown(full_answer) | |
| status_container.update(label="β μ²λ¦¬ μλ£", state="complete", expanded=False) | |
| if received_docs: | |
| with st.expander("μ°Έκ³ λ¬Έμ"): | |
| for idx, doc in enumerate(received_docs): | |
| st.info(f"**{doc['source']}**: {doc['content']}") | |
| st.session_state.messages.append({ | |
| "role": "assistant", | |
| "content": full_answer, | |
| "docs": received_docs | |
| }) | |
| except Exception as e: | |
| status_container.update(label="β μ€λ₯ λ°μ", state="error") | |
| st.error(f"Connection Error: {e}") |