import streamlit as st st.set_page_config( page_title="Instant - Indonesia Immigration Assistant", layout="centered", initial_sidebar_state="expanded" ) from pymongo import MongoClient from langchain_mongodb import MongoDBAtlasVectorSearch from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from dotenv import load_dotenv from streamlit_option_menu import option_menu import os import re from model import ask from handler import save_feedback, translate_answer, check_question_feedback, translate_text, is_overlimit, refresh_web_counter from text import feedback_instr, no_affiliation, description, no_replacement_for_official_advice, source_of_answer_short, source_of_answer from langdetect import detect from deep_translator import GoogleTranslator from datetime import datetime primary_color = "#ffffff" secondary_color = "#1E1E1E" accent_color = "#FF6B35" sidebar_bg = "#0e1117" sidebar_text = "#ffffff" selected_bg = "#f39c12" selected_text = "#000000" text_color = "#000000" bg_color = "#252422" header = "#1E1E1E" # --- Custom CSS --- st.markdown(f""" """, unsafe_allow_html=True) current_hour = datetime.now().hour local_hour = (current_hour + 7) % 24 working_hours = (8 <= local_hour < 20) extra_remark = " (GMT+7)" # Sidebar Menu with st.sidebar: selected = option_menu( "Menu", ["Chatbot", "About", "Contact"], icons=["chat-dots", "info-circle", "telephone"], menu_icon="cast", default_index=0, styles={ "container": {"padding": "5!important", "background-color": sidebar_bg}, "icon": {"color": accent_color, "font-size": "25px"}, "nav-link": {"color": sidebar_text, "font-size": "16px", "text-align": "left", "margin":"0px"}, "nav-link-selected": {"background-color": selected_bg, "color": selected_text}, } ) def get_second_last_user_message(): count = 0 for msg in reversed(st.session_state.messages): if msg["role"] == "user": count += 1 if count == 2: return msg["content"] return None def get_last_user_message(): for msg in reversed(st.session_state.messages): if msg["role"] == "user" and msg["type"] == "question": return msg["content"] return None def get_last_assistant_message(): for msg in reversed(st.session_state.messages): if msg["role"] == "assistant" and msg["type"] == "answer": return msg["content"] return None def normalize(text): return re.sub(r'[^\w\s]', '', text).strip().lower() def separate_feedback_from_query(user_input, normalized_feedbacks): question = get_last_user_message() answer = get_last_assistant_message() cleaned_input = normalize(user_input) if cleaned_input in normalized_feedbacks: return {"type": "pure_feedback", "feedback": cleaned_input, "comment": "", "question": question, "answer": answer} # Try to match a known feedback prefix for keyword in normalized_feedbacks: if cleaned_input.startswith(keyword): remaining = cleaned_input[len(keyword):].strip() return { "type": "mixed", "feedback": keyword, "comment": remaining, "question": question, "answer": answer } return {"type": "normal_query", "feedback": None, "comment": user_input, "question": question, "answer": answer} def normalize(text): return re.sub(r'[^\w\s]', '', text).strip().lower() # --- Streamlit UI --- if selected == "Chatbot": with st.container(): col1, col2 = st.columns([4, 4]) with col1: st.image("instant.png", width=1000) with col2: st.markdown(f"""
{no_affiliation}
{source_of_answer_short}