🏛️ FAR Chatbot
Federal Acquisition Regulation Assistant
#!/usr/bin/env python3 """ FAR Chatbot - Hugging Face Spaces Version Federal Acquisition Regulation Assistant with Clickable Citations """ import streamlit as st import time import logging import os import sys import re from datetime import datetime # Configure logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) # Import the chatbot from far_chatbot import FARChatbot try: import markdown except ImportError: markdown = None # Configure page st.set_page_config( page_title="FAR Chatbot - Federal Acquisition Regulation Assistant", page_icon="🏛️", layout="wide", initial_sidebar_state="expanded" ) # Authentication VALID_CREDENTIALS = {"testuser": "farbot2025"} def check_password(): def password_entered(): username = st.session_state.get("username", "") password = st.session_state.get("password", "") if username in VALID_CREDENTIALS and VALID_CREDENTIALS[username] == password: st.session_state["authenticated"] = True del st.session_state["password"] else: st.session_state["authenticated"] = False if "authenticated" not in st.session_state: st.session_state["authenticated"] = False if not st.session_state["authenticated"]: col1, col2, col3 = st.columns([1, 2, 1]) with col2: st.markdown("## 🏛️ FAR Chatbot Login") st.text_input("Username", key="username") st.text_input("Password", type="password", key="password") st.button("🔐 Log In", on_click=password_entered, type="primary", use_container_width=True) if st.session_state.get("authenticated") == False and "username" in st.session_state and st.session_state["username"]: st.error("❌ Invalid credentials") return False return True if not check_password(): st.stop() # CSS Styling st.markdown(""" """, unsafe_allow_html=True) # Session state if 'chatbot' not in st.session_state: st.session_state.chatbot = None if 'chat_history' not in st.session_state: st.session_state.chat_history = [] if 'show_sources' not in st.session_state: st.session_state.show_sources = True @st.cache_resource def load_chatbot(): """Load the FAR chatbot""" try: logger.info("Loading FAR Chatbot...") chatbot = FARChatbot( faiss_index_path="data/faiss_index.index", texts_path="data/texts.txt", use_gpt5=True ) return chatbot except Exception as e: logger.error(f"Error loading chatbot: {e}") st.error(f"Error loading chatbot: {e}") return None def get_acquisition_gov_url(citation: str) -> str: base_citation = re.sub(r'\([a-z]\)$', '', citation) return f"https://www.acquisition.gov/far/{base_citation}" def make_citations_clickable(response: str, search_results: list) -> str: if not markdown: return response text = response def make_link(citation): url = get_acquisition_gov_url(citation) return f'' # Replace citation patterns text = re.sub(r'\[FAR\s+(\d+\.\d+(?:-\d+)?(?:\([a-z]\))?)\]', lambda m: f'{make_link(m.group(1))}[{m.group(1)}]', text) text = re.sub(r'\[(\d+\.\d+(?:-\d+)?(?:\([a-z]\))?)\]', lambda m: f'{make_link(m.group(1))}[{m.group(1)}]', text) text = re.sub(r'(?', text) return markdown.markdown(text, extensions=['tables', 'fenced_code', 'nl2br']) # Header st.markdown("""
Federal Acquisition Regulation Assistant