Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| import os | |
| from src.data_processor import LegalDocProcessor | |
| from src.hybrid_retriever import HybridRetriever | |
| # --- Configuration & Initialization --- | |
| INDEX_DIR = "index_storage" | |
| PARENT_DATA = "data/parent_docs.json" | |
| CHILD_DATA = "data/child_docs.json" | |
| def initialize_retriever(): | |
| try: | |
| if os.path.exists(INDEX_DIR): | |
| print("[*] Loading existing index...") | |
| return HybridRetriever(index_dir=INDEX_DIR) | |
| else: | |
| print("[*] Building new index...") | |
| processor = LegalDocProcessor(PARENT_DATA, CHILD_DATA) | |
| docs = processor.load_and_clean() | |
| if not docs: | |
| return None | |
| ret = HybridRetriever(documents=docs, index_dir=INDEX_DIR) | |
| ret.save_index() | |
| return ret | |
| except Exception as e: | |
| print(f"Error initializing retriever: {e}") | |
| return None | |
| # Global retriever instance | |
| retriever = initialize_retriever() | |
| def respond( | |
| message, | |
| history, | |
| system_message, | |
| max_tokens, | |
| temperature, | |
| top_p, | |
| hf_token: gr.OAuthToken | None = None, | |
| ): | |
| # 1. RETRIEVAL STEP | |
| context = "" | |
| if retriever: | |
| try: | |
| search_results = retriever.hybrid_search(message, top_k=3) | |
| context = "\n\nRELEVANT NEPALESE LAW CONTEXT:\n" | |
| if not search_results: | |
| context += "No specific legal clauses found for this query." | |
| for res in search_results: | |
| src = res.get('legal_document_source', 'Unknown') | |
| cid = res.get('parent_clause_id', 'N/A') | |
| txt = res.get('parent_clause_text', 'Text not found') | |
| context += f"--- Source: {src} ---\nClause: {cid}\nText: {txt}\n\n" | |
| except Exception as e: | |
| print(f"Retrieval Error: {e}") | |
| context = "\n(Error retrieving specific law context.)" | |
| # 2. PROMPT ENGINEERING | |
| augmented_system_message = ( | |
| f"{system_message}\n\n" | |
| "You are a legal assistant specializing in Nepalese Law. " | |
| "Use the legal context provided below to answer. Cite the Source and Clause ID.\n" | |
| f"{context}" | |
| ) | |
| # 3. TOKEN SETUP | |
| raw_token = hf_token.token if (hf_token and hasattr(hf_token, 'token')) else os.getenv("HF_TOKEN", "") | |
| token = raw_token.strip() if raw_token else None | |
| if not token: | |
| yield "⚠️ Error: Please sign in with Hugging Face (see sidebar) or set HF_TOKEN secret." | |
| return | |
| client = InferenceClient(token=token, model="meta-llama/Llama-3.1-70B-Instruct") | |
| # 4. UNIVERSAL HISTORY PARSER (Handles both List of Lists and List of Dicts) | |
| messages = [{"role": "system", "content": augmented_system_message}] | |
| for item in history: | |
| if isinstance(item, dict): | |
| # Gradio 5 or Newer Gradio 4 format: {"role": "user", "content": "..."} | |
| messages.append({"role": item["role"], "content": item["content"]}) | |
| elif isinstance(item, (list, tuple)): | |
| # Traditional Gradio 4 format: [user_msg, bot_msg] | |
| u, a = item | |
| if u: messages.append({"role": "user", "content": u}) | |
| if a: messages.append({"role": "assistant", "content": a}) | |
| messages.append({"role": "user", "content": message}) | |
| # 5. GENERATION | |
| response = "" | |
| try: | |
| for msg in client.chat_completion( | |
| messages, | |
| max_tokens=max_tokens, | |
| stream=True, | |
| temperature=temperature, | |
| top_p=top_p, | |
| ): | |
| token_text = msg.choices[0].delta.content | |
| if token_text: | |
| response += token_text | |
| yield response | |
| except Exception as e: | |
| yield f"AI Error: {str(e)}" | |
| # --- Gradio UI Setup --- | |
| chatbot = gr.ChatInterface( | |
| respond, | |
| # REMOVED type="messages" to fix TypeError | |
| additional_inputs=[ | |
| gr.Textbox(value="You are a helpful Nepalese Legal Advisor.", label="System message"), | |
| gr.Slider(minimum=1, maximum=2048, value=1024, step=1, label="Max tokens"), | |
| gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"), | |
| gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"), | |
| ], | |
| title="Nepal Law Search AI", | |
| description="Ask questions about Nepalese Constitution and Acts.", | |
| examples=[ | |
| ["What are the punishments for cybercrime?"], | |
| ["What does the constitution say about the right to equality?"], | |
| ["Is witchcraft accusation a crime in Nepal?"] | |
| ], | |
| cache_examples=False, | |
| ) | |
| with gr.Blocks() as demo: | |
| with gr.Sidebar(): | |
| gr.Markdown("### Authentication") | |
| gr.LoginButton() | |
| gr.Markdown("---") | |
| gr.Markdown("**Status:** Database Ready ✅") | |
| chatbot.render() | |
| if __name__ == "__main__": | |
| # Disable SSR to avoid Python 3.13 asyncio noise | |
| demo.launch(ssr_mode=False, show_error=True) |