CoolFace
Apppublic

Rulga/LS-chatbot-log

sourceHugging Faceupdated 2y agoView on Hugging Face
1likes
app.py200 linesDownload Raw Back to root
1import os2import time3import json4import traceback5from datetime import datetime6import streamlit as st7from dotenv import load_dotenv8from langchain_groq import ChatGroq9from langchain_huggingface import HuggingFaceEmbeddings10from langchain_community.vectorstores import FAISS11from langchain_text_splitters import RecursiveCharacterTextSplitter12from langchain_community.document_loaders import WebBaseLoader13from langchain_core.prompts import PromptTemplate14from langchain_core.output_parsers import StrOutputParser15 16# Initialize environment variables17load_dotenv()18 19# --------------- Enhanced Logging System ---------------20def log_interaction(user_input: str, bot_response: str, context: str):21    """Log user interactions with context and error handling"""22    try:23        log_entry = {24            "timestamp": datetime.now().isoformat(),25            "user_input": user_input,26            "bot_response": bot_response,27            "context": context,28            "model": "llama-3.3-70b-versatile",29            "kb_version": st.session_state.kb_info.get('version', '1.0')30        }31        32        os.makedirs("chat_history", exist_ok=True)33        log_path = os.path.join("chat_history", "chat_logs.json")34        35        # Atomic write operation with UTF-8 encoding36        with open(log_path, "a", encoding="utf-8") as f:37            f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")38            39    except Exception as e:40        error_msg = f"Logging error: {str(e)}\n{traceback.format_exc()}"41        print(error_msg)42        st.error("Error saving interaction log. Please contact support.")43 44# --------------- Page Configuration ---------------45st.set_page_config(46    page_title="Status Law Assistant",47    page_icon="⚖️",48    layout="wide",49    menu_items={50        'About': "### Legal AI Assistant powered by Status.Law"51    }52)53 54# --------------- Knowledge Base Management ---------------55VECTOR_STORE_PATH = "vector_store"56URLS = [57    "https://status.law",  58    "https://status.law/about",59    "https://status.law/careers",  60    "https://status.law/tariffs-for-services-of-protection-against-extradition",61    "https://status.law/challenging-sanctions",62    "https://status.law/law-firm-contact-legal-protection"63    "https://status.law/cross-border-banking-legal-issues", 64    "https://status.law/extradition-defense", 65    "https://status.law/international-prosecution-protection", 66    "https://status.law/interpol-red-notice-removal",  67    "https://status.law/practice-areas",  68    "https://status.law/reputation-protection",69    "https://status.law/faq"70]71 72def init_models():73    """Initialize AI models with caching"""74    llm = ChatGroq(75        model_name="llama-3.3-70b-versatile",76        temperature=0.6,77        api_key=os.getenv("GROQ_API_KEY")78    )79    embeddings = HuggingFaceEmbeddings(80        model_name="intfloat/multilingual-e5-large-instruct"81    )82    return llm, embeddings83 84def build_knowledge_base(embeddings):85    """Create or update the vector knowledge base"""86    start_time = time.time()87    88    documents = []89    with st.status("Building knowledge base..."):90        for url in URLS:91            try:92                loader = WebBaseLoader(url)93                documents.extend(loader.load())94            except Exception as e:95                st.error(f"Failed to load {url}: {str(e)}")96    97    text_splitter = RecursiveCharacterTextSplitter(98        chunk_size=500,99        chunk_overlap=100100    )101    chunks = text_splitter.split_documents(documents)102    103    vector_store = FAISS.from_documents(chunks, embeddings)104    vector_store.save_local(VECTOR_STORE_PATH)105    106    # Update version information107    st.session_state.kb_info.update({108        'build_time': time.time() - start_time,109        'size': sum(os.path.getsize(f) for f in os.listdir(VECTOR_STORE_PATH)) / (1024 ** 2),110        'version': datetime.now().strftime("%Y%m%d-%H%M%S")111    })112    113    return vector_store114 115# --------------- Chat Interface ---------------116def main():117    llm, embeddings = init_models()118    119    # Initialize or load knowledge base120    if not os.path.exists(VECTOR_STORE_PATH):121        if st.button("Initialize Knowledge Base"):122            with st.spinner("Creating knowledge base..."):123                st.session_state.vector_store = build_knowledge_base(embeddings)124                st.rerun()125        return126    127    if 'vector_store' not in st.session_state:128        st.session_state.vector_store = FAISS.load_local(129            VECTOR_STORE_PATH, embeddings, allow_dangerous_deserialization=True130        )131    132    # Display chat history133    if 'messages' not in st.session_state:134        st.session_state.messages = []135    136    for msg in st.session_state.messages:137        st.chat_message(msg["role"]).write(msg["content"])138    139    # Process user input140    if user_input := st.chat_input("Ask your legal question"):141        # Display user message142        st.chat_message("user").write(user_input)143        144        with st.chat_message("assistant"):145            with st.spinner("Analyzing your question..."):146                try:147                    # Retrieve relevant context148                    context_docs = st.session_state.vector_store.similarity_search(user_input)149                    context_text = "\n".join(d.page_content for d in context_docs)150                    151                    # Generate response152                    prompt_template = PromptTemplate.from_template("""153                    You are a helpful and polite legal assistant at Status Law.154                    You answer in the language in which the question was asked.155                    Answer the question based on the context provided.156                    If you cannot answer based on the context, say so politely and offer to contact Status Law directly via the following channels:157                    - For all users: +32465594521 (landline phone).158                    - For English and Swedish speakers only: +46728495129 (available on WhatsApp, Telegram, Signal, IMO).159                    - Provide a link to the contact form: [Contact Form](https://status.law/law-firm-contact-legal-protection/).160                    If the user has questions about specific services and their costs, suggest they visit the page https://status.law/tariffs-for-services-of-protection-against-extradition-and-international-prosecution/ for detailed information.161 162                    Ask the user additional questions to understand which service to recommend and provide an estimated cost. For example, clarify their situation and needs to suggest the most appropriate options.163 164                    Also, offer free consultations if they are available and suitable for the user's request.165                    Answer professionally but in a friendly manner.166 167                    Example:168                    Q: How can I challenge the sanctions?169                    A: To challenge the sanctions, you should consult with our legal team, who specialize in this area. Please contact us directly for detailed advice. You can fill out our contact form here: [Contact Form](https://status.law/law-firm-contact-legal-protection/).170 171                    Context: {context}172                    Question: {question}173                    174                    Response Guidelines:175                    1. Answer in the user's language176                    2. Cite sources when possible177                    3. Offer contact options if unsure178                    """)179                    180                    response = (prompt_template | llm | StrOutputParser()).invoke({181                        "context": context_text,182                        "question": user_input183                    })184                    185                    # Display and log interaction186                    st.write(response)187                    log_interaction(user_input, response, context_text)188                    st.session_state.messages.extend([189                        {"role": "user", "content": user_input},190                        {"role": "assistant", "content": response}191                    ])192                    193                except Exception as e:194                    error_msg = f"Processing error: {str(e)}\n{traceback.format_exc()}"195                    st.error("Error processing request. Please try again.")196                    print(error_msg)197                    log_interaction(user_input, "SYSTEM_ERROR", context_text)198 199if __name__ == "__main__":200    main()