"""app.py — Gradio UI for BERTopic Multi-Agent Research. Zero if/else/for/while/try/except.""" import sys, os; sys.stdout.reconfigure(line_buffering=True) from dotenv import load_dotenv load_dotenv() os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python" import json, glob print(">>> importing gradio...", flush=True) import gradio as gr print(">>> importing agents...", flush=True) from agents import build_agent from tools import PAPER_CACHE, OUTPUT_DIR, supabase print(">>> building agent...", flush=True) agent = build_agent() _msg_count = 0 print(">>> agent ready!", flush=True) def _pipeline(phase): phases = [("① Load", 1), ("② Codes", 2), ("③ Themes", 3), ("④ Review", 4), ("⑤ Names", 5), ("⑤½ PAJAIS", 5.5), ("⑥ Report", 6)] return " → ".join(list(map(lambda p: f"**{p[0]}**" if p[1]==phase else (f"✅ {p[0]}" if p[1]", False: lambda: fallback}[os.path.exists(path)]() print(">>> fetching history...", flush=True) def show_topic_papers(evt: gr.SelectData, chat_id_state): if not chat_id_state: return [] row = evt.index[0] chat = supabase.table("chats").select("topics_json").eq("id", chat_id_state).execute().data[0] tops = chat.get("topics_json", []) if chat.get("topics_json") else [] if row >= len(tops): return [] papers = supabase.table("papers").select("title,web_link,date_of_publication,journal,no_of_citations,confidence_score").eq("topic_label", tops[row]["label"]).eq("chat_id", chat_id_state).execute().data return list(map(lambda p: [p.get("title", ""), p.get("web_link", ""), p.get("date_of_publication", ""), p.get("journal", ""), p.get("no_of_citations", ""), p.get("confidence_score", "")], papers)) hist = _history() print(f">>> {len(hist)} past sessions", flush=True) print(">>> building UI...", flush=True) with gr.Blocks(title="BERTopic — Digital Social Innovation") as demo: gr.Markdown("# 🔬 Topic Modelling — Agentic AI\n*Qwen 72B 🧠 · MiniLM Embeddings · Cosine Clustering · 384d · Braun & Clarke Thematic Analysis*") pipeline_html = gr.Markdown(_pipeline(1)) gr.Markdown("💡 **Multi-Agent Architecture:** Supervisor Agent orchestrates 4 workers (OpenAlex, Tavily, Scopus, Validation) + 1 analysis worker (BERTopic embedding → clustering → LLM labeling → Supabase upload)") chat_state = gr.State(None) chatbot = gr.Chatbot(height=320, show_label=False) with gr.Row(): msg = gr.Textbox(placeholder="e.g. 'digital social innovation and societal impact'", show_label=False, scale=9, container=False) send = gr.Button("Send", scale=1, min_width=70) with gr.Row(): cmd1 = gr.Button("▶ Digital Social Innovation", size="sm") cmd2 = gr.Button("▶ AI in Healthcare", size="sm") cmd3 = gr.Button("▶ Sustainable Tourism Tech", size="sm") with gr.Tabs(): with gr.TabItem("📋 Review Table"): review_table = gr.Dataframe(headers=["#","Topic Label","Top Evidence","Sents","Papers","Approve","Rename To","Reasoning"], datatype=["number","str","str","number","number","str","str","str"], interactive=True) submit_btn = gr.Button("✅ Submit Review to Agent") review_out = gr.Textbox(label="Review Status", interactive=False) gr.Markdown("🛑 **STOP Gate** — Agent pauses here. Review each BERTopic cluster label. Edit Approve/Rename columns → click Submit.") gr.Markdown("📄 **Papers in Selected Topic**") paper_table = gr.Dataframe(headers=["Title", "Source", "Year", "Journal", "Citations", "Relevance Score"], interactive=False) with gr.TabItem("📊 Charts"): chart_dd = gr.Dropdown(choices=["rq4_abstract_bars.html","rq4_abstract_heatmap.html","rq4_abstract_intertopic.html"], value="rq4_abstract_bars.html", label="Select Visualization") chart_html = gr.HTML("
📊 Charts appear here after BERTopic analysis
") with gr.TabItem("📥 Downloads"): download_files = gr.File(label="Output Files (summaries.json, emb.npy, charts, CSV)", file_count="multiple", interactive=False) history_dd = gr.Dropdown(choices=hist, label="📚 Past Research Sessions (Supabase)", interactive=True) msg.submit(respond, [msg, chatbot], [chatbot, msg, pipeline_html, review_table, download_files, chat_state]) send.click(respond, [msg, chatbot], [chatbot, msg, pipeline_html, review_table, download_files, chat_state]) submit_btn.click(submit_review, [review_table], [review_out]) review_table.select(show_topic_papers, inputs=[chat_state], outputs=[paper_table]) chart_dd.change(load_chart, [chart_dd], [chart_html]) cmd1.click(lambda: "digital social innovation and societal impact", outputs=[msg]) cmd2.click(lambda: "artificial intelligence in healthcare diagnosis", outputs=[msg]) cmd3.click(lambda: "sustainable tourism technology adoption", outputs=[msg]) print(">>> launching...", flush=True) demo.launch(server_name="0.0.0.0")