Spaces:
Running
Running
""" | |
Trợ lý AI ViettelPay - Giao diện Streamlit cho cuộc trò chuyện đa lượt | |
""" | |
import streamlit as st | |
import os | |
import uuid | |
import time | |
# For backward compatibility with local development using .env files | |
try: | |
from dotenv import load_dotenv | |
load_dotenv() | |
except ImportError: | |
pass # dotenv not required in production | |
# Simple page config | |
st.set_page_config(page_title="Trợ lý AI ViettelPay", page_icon="💳", layout="centered") | |
# Header | |
st.title("💳 Trợ lý AI ViettelPay") | |
st.caption("Trợ lý ảo hỗ trợ dịch vụ ViettelPay Pro - Cuộc trò chuyện đa lượt") | |
# Initialize session state | |
if "messages" not in st.session_state: | |
st.session_state.messages = [] | |
if "agent" not in st.session_state: | |
st.session_state.agent = None | |
if "agent_initialization_status" not in st.session_state: | |
st.session_state.agent_initialization_status = "not_started" | |
if "thread_id" not in st.session_state: | |
# Generate a unique thread ID for this session | |
st.session_state.thread_id = str(uuid.uuid4())[:8] | |
if "conversation_started" not in st.session_state: | |
st.session_state.conversation_started = False | |
def initialize_agent(): | |
"""Khởi tạo agent ViettelPay với bộ nhớ đệm""" | |
try: | |
from src.agent.viettelpay_agent import ViettelPayAgent | |
return ViettelPayAgent() | |
except Exception as e: | |
st.error(f"❌ Lỗi khởi tạo agent: {str(e)}") | |
return None | |
# Auto-initialize agent when app starts | |
if ( | |
st.session_state.agent is None | |
and st.session_state.agent_initialization_status == "not_started" | |
): | |
st.session_state.agent_initialization_status = "initializing" | |
with st.spinner("🚀 Đang khởi tạo Trợ lý AI ViettelPay..."): | |
st.session_state.agent = initialize_agent() | |
if st.session_state.agent: | |
st.session_state.agent_initialization_status = "success" | |
st.success("✅ Khởi tạo agent thành công!") | |
else: | |
st.session_state.agent_initialization_status = "failed" | |
st.error("❌ Khởi tạo agent thất bại") | |
# Sidebar | |
with st.sidebar: | |
st.header("🛠️ Điều khiển") | |
# Agent status | |
if st.session_state.agent_initialization_status == "initializing": | |
st.info("🔄 Đang khởi tạo agent...") | |
elif st.session_state.agent_initialization_status == "success": | |
st.success("✅ Agent đã sẵn sàng!") | |
# Health check | |
if st.button("🏥 Kiểm tra tình trạng"): | |
try: | |
health = st.session_state.agent.health_check() | |
for component, status in health.items(): | |
if component != "overall": | |
icon = "✅" if status else "❌" | |
st.write(f"{icon} {component}") | |
except Exception as e: | |
st.error(f"Kiểm tra tình trạng thất bại: {e}") | |
elif st.session_state.agent_initialization_status == "failed": | |
st.error("❌ Khởi tạo agent thất bại") | |
if st.button("🔄 Thử lại khởi tạo"): | |
st.session_state.agent_initialization_status = "not_started" | |
st.session_state.agent = None | |
st.rerun() | |
st.divider() | |
# Conversation Management | |
st.subheader("💬 Cuộc trò chuyện") | |
# Show current thread ID | |
st.write(f"**ID Cuộc trò chuyện:** `{st.session_state.thread_id}`") | |
# Show conversation stats | |
if st.session_state.agent and st.session_state.conversation_started: | |
try: | |
history = st.session_state.agent.get_conversation_history( | |
st.session_state.thread_id | |
) | |
st.write(f"**Số tin nhắn:** {len(history)}") | |
except: | |
st.write("**Số tin nhắn:** Không thể đếm") | |
# Clear current conversation | |
if st.button("🗑️ Xóa cuộc trò chuyện"): | |
st.session_state.messages = [] | |
st.session_state.conversation_started = False | |
if st.session_state.agent: | |
st.session_state.agent.clear_conversation(st.session_state.thread_id) | |
st.rerun() | |
# Start new conversation | |
if st.button("🆕 Cuộc trò chuyện mới"): | |
st.session_state.messages = [] | |
st.session_state.thread_id = str(uuid.uuid4())[:8] | |
st.session_state.conversation_started = False | |
st.rerun() | |
st.divider() | |
# Conversation History Viewer | |
if st.session_state.agent and st.session_state.conversation_started: | |
st.subheader("📜 Lịch sử") | |
if st.button("🔍 Xem toàn bộ lịch sử"): | |
try: | |
history = st.session_state.agent.get_conversation_history( | |
st.session_state.thread_id | |
) | |
with st.expander("Lịch sử cuộc trò chuyện đầy đủ", expanded=True): | |
for i, msg in enumerate(history, 1): | |
role_icon = "👤" if msg["role"] == "user" else "🤖" | |
role_text = "Người dùng" if msg["role"] == "user" else "Trợ lý" | |
st.write(f"{i}. {role_icon} **{role_text}:** {msg['content']}") | |
except Exception as e: | |
st.error(f"Lỗi tải lịch sử: {e}") | |
# Main chat area | |
st.subheader("💬 Trò chuyện") | |
# Display messages | |
for msg in st.session_state.messages: | |
if msg["role"] == "user": | |
with st.chat_message("user"): | |
st.write(msg["content"]) | |
elif msg["role"] == "assistant": | |
with st.chat_message("assistant"): | |
st.write(msg["content"]) | |
# Show metadata if available | |
if "metadata" in msg: | |
with st.expander("📊 Chi tiết"): | |
metadata = msg["metadata"] | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
st.metric("Ý định", metadata.get("intent", "không xác định")) | |
with col2: | |
st.metric("Độ tin cậy", f"{metadata.get('confidence', 0):.2f}") | |
with col3: | |
st.metric( | |
"Loại", metadata.get("response_type", "không xác định") | |
) | |
# Show enhanced query if available and different from original | |
if metadata.get("enhanced_query"): | |
st.write( | |
f"**🚀 Câu hỏi được tối ưu:** {metadata['enhanced_query']}" | |
) | |
if metadata.get("thread_id"): | |
st.write(f"**Cuộc trò chuyện:** {metadata['thread_id']}") | |
if metadata.get("message_count"): | |
st.write(f"**Tổng số tin nhắn:** {metadata['message_count']}") | |
elif msg["role"] == "error": | |
st.error(msg["content"]) | |
# Chat input | |
if prompt := st.chat_input("Nhập câu hỏi của bạn..."): | |
if st.session_state.agent is None: | |
st.error("Vui lòng đợi quá trình khởi tạo agent hoàn thành!") | |
st.stop() | |
# Mark conversation as started | |
st.session_state.conversation_started = True | |
# Add user message | |
st.session_state.messages.append({"role": "user", "content": prompt}) | |
# Process message | |
try: | |
with st.spinner("Đang xử lý..."): | |
# Use the session's thread_id for conversation continuity | |
# Check the time processing | |
start_time = time.time() | |
result = st.session_state.agent.process_message( | |
prompt, st.session_state.thread_id | |
) | |
end_time = time.time() | |
processing_time = end_time - start_time | |
print(f"Thời gian xử lý: {processing_time:.2f} giây") | |
# Add response | |
st.session_state.messages.append( | |
{ | |
"role": "assistant", | |
"content": result["response"], | |
"metadata": { | |
"intent": result.get("intent"), | |
"confidence": result.get("confidence"), | |
"response_type": result.get("response_type"), | |
"enhanced_query": result.get("enhanced_query"), | |
"success": result.get("success"), | |
"thread_id": result.get("thread_id"), | |
"message_count": result.get("message_count"), | |
}, | |
} | |
) | |
if result.get("error"): | |
st.session_state.messages.append( | |
{"role": "error", "content": f"Lỗi: {result['error']}"} | |
) | |
except Exception as e: | |
st.session_state.messages.append( | |
{"role": "error", "content": f"Lỗi hệ thống: {str(e)}"} | |
) | |
st.rerun() | |
# Footer | |
st.caption( | |
"🚀 Được hỗ trợ bởi LangGraph & Gemini AI | Cuộc trò chuyện đa lượt với InMemorySaver" | |
) | |