{"repo": "anamicca23/resolvabot-llm", "files": {"app.py": {"23995428027237c868eacbb82f214e53f29caff1": {"t": 1785674394.1982868, "n": 54928, "h": "bf14938266734e29", "c": "\"\"\"\napp.py β ResolvaBot LLM (All 7 UI fixes applied)\n\"\"\"\nimport os, sys, re, html, base64\nimport streamlit as st\nimport streamlit.components.v1 as components\nfrom dotenv import load_dotenv\n\nSRC = os.path.join(os.path.dirname(__file__), \"src\")\nif SRC not in sys.path: sys.path.insert(0, SRC)\nload_dotenv()\n\nst.set_page_config(\n page_title=\"ResolvaBot LLM\", page_icon=\"π\",\n layout=\"wide\", initial_sidebar_state=\"collapsed\",\n)\n\n# ββ Themes ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\nTHEMES = {\n \"dark\": {\"name\":\"Dark\", \"ac\":\"#58a6ff\",\"ac2\":\"#8b5cf6\",\"rgb\":\"88,166,255\",\n \"page\":\"#0d1117\",\"card\":\"#161b22\",\"panel\":\"#1c2333\",\"inp\":\"#1f2937\",\n \"b1\":\"#30363d\",\"b2\":\"#21262d\",\"t1\":\"#e6edf3\",\"t2\":\"#8b949e\",\"t3\":\"#484f58\",\n \"green\":\"#3fb950\",\"gbg\":\"rgba(63,185,80,.12)\",\"shd\":\"0 8px 32px rgba(0,0,0,.5)\"},\n \"light\": {\"name\":\"Light\", \"ac\":\"#0969da\",\"ac2\":\"#7c3aed\",\"rgb\":\"9,105,218\",\n \"page\":\"#f6f8fa\",\"card\":\"#ffffff\",\"panel\":\"#f0f4f8\",\"inp\":\"#f8fafc\",\n \"b1\":\"#d0d7de\",\"b2\":\"#e2e8f0\",\"t1\":\"#0d1117\",\"t2\":\"#57606a\",\"t3\":\"#9ca3af\",\n \"green\":\"#1a7f37\",\"gbg\":\"rgba(26,127,55,.08)\",\"shd\":\"0 4px 16px rgba(0,0,0,.1)\"},\n \"indigo\": {\"name\":\"Indigo\", \"ac\":\"#7c6af7\",\"ac2\":\"#e86af7\",\"rgb\":\"124,106,247\",\n \"page\":\"#0f0e17\",\"card\":\"#16152a\",\"panel\":\"#1c1b33\",\"inp\":\"#211f3c\",\n \"b1\":\"#2e2b52\",\"b2\":\"#3a3760\",\"t1\":\"#fffffe\",\"t2\":\"#a7a9be\",\"t3\":\"#5c5a7e\",\n \"green\":\"#3ecf8e\",\"gbg\":\"rgba(62,207,142,.1)\",\"shd\":\"0 8px 32px rgba(0,0,0,.6)\"},\n \"teal\": {\"name\":\"Teal\", \"ac\":\"#2dd4bf\",\"ac2\":\"#22d3ee\",\"rgb\":\"45,212,191\",\n \"page\":\"#0a1628\",\"card\":\"#0f2237\",\"panel\":\"#122840\",\"inp\":\"#163048\",\n \"b1\":\"#1e3d55\",\"b2\":\"#254d6b\",\"t1\":\"#e2f4ff\",\"t2\":\"#7db3cc\",\"t3\":\"#3d7090\",\n \"green\":\"#34d399\",\"gbg\":\"rgba(52,211,153,.1)\",\"shd\":\"0 8px 32px rgba(0,0,0,.5)\"},\n \"rose\": {\"name\":\"Rose\", \"ac\":\"#f43f5e\",\"ac2\":\"#ec4899\",\"rgb\":\"244,63,94\",\n \"page\":\"#0f0a0c\",\"card\":\"#1a0f13\",\"panel\":\"#22141a\",\"inp\":\"#2a1820\",\n \"b1\":\"#3d1f28\",\"b2\":\"#4d2535\",\"t1\":\"#fff1f3\",\"t2\":\"#fca5a5\",\"t3\":\"#6b2737\",\n \"green\":\"#34d399\",\"gbg\":\"rgba(52,211,153,.1)\",\"shd\":\"0 8px 32px rgba(0,0,0,.6)\"},\n \"amber\": {\"name\":\"Amber\", \"ac\":\"#f59e0b\",\"ac2\":\"#ef4444\",\"rgb\":\"245,158,11\",\n \"page\":\"#0c0a04\",\"card\":\"#1a1504\",\"panel\":\"#221d06\",\"inp\":\"#2a2408\",\n \"b1\":\"#3d3410\",\"b2\":\"#4d4218\",\"t1\":\"#fefce8\",\"t2\":\"#fde68a\",\"t3\":\"#713f12\",\n \"green\":\"#34d399\",\"gbg\":\"rgba(52,211,153,.1)\",\"shd\":\"0 8px 32px rgba(0,0,0,.6)\"},\n \"mono\": {\"name\":\"Mono\", \"ac\":\"#94a3b8\",\"ac2\":\"#64748b\",\"rgb\":\"148,163,184\",\n \"page\":\"#0a0a0a\",\"card\":\"#111111\",\"panel\":\"#1a1a1a\",\"inp\":\"#222222\",\n \"b1\":\"#2d2d2d\",\"b2\":\"#3d3d3d\",\"t1\":\"#f8f8f8\",\"t2\":\"#a0a0a0\",\"t3\":\"#555555\",\n \"green\":\"#34d399\",\"gbg\":\"rgba(52,211,153,.1)\",\"shd\":\"0 8px 32px rgba(0,0,0,.7)\"},\n}\n\n# ββ Session state defaults βββββββββββββββββββββββββββββββββββββββββββββββββββββ\nfor k, v in dict(\n view=\"upload\", theme=\"dark\", sidebar_open=False,\n indexed=False, retriever=None, history=[],\n last_file=\"\", last_file_bytes=None,\n pages=0, chunks=0, nodes=0, file_size=\"\", step=0,\n cur_passages=[],\n groq_key=os.getenv(\"GROQ_API_KEY\",\"\"),\n openai_key=os.getenv(\"OPENAI_API_KEY\",\"\"),\n).items():\n if k not in st.session_state: st.session_state[k] = v\n\nif st.session_state.groq_key: os.environ[\"GROQ_API_KEY\"] = st.session_state.groq_key\nif st.session_state.openai_key:os.environ[\"OPENAI_API_KEY\"] = st.session_state.openai_key\nhas_groq = bool(os.getenv(\"GROQ_API_KEY\",\"\").strip())\nhas_openai = bool(os.getenv(\"OPENAI_API_KEY\",\"\").strip())\n\nT = THEMES[st.session_state.theme]\nac = T[\"ac\"]; ac2 = T[\"ac2\"]; rgb = T[\"rgb\"]\n\ndef go(v): st.session_state.view = v; st.rerun()\ndef detect_lang(t):\n if re.search(r'#include|cout|cin|vector<|int main', t): return \"cpp\"\n if re.search(r'\\bdef \\b|\\bimport \\b|print\\(', t): return \"python\"\n if re.search(r'public class|System\\.out', t): return \"java\"\n return \"text\"\ndef pill(text, cls=\"ps\"):\n return f'{text}'\n\nst.markdown(f\"\"\"\n\n\"\"\", unsafe_allow_html=True)\n\n# ββ Helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\ndef mpill(model, src):\n if model.startswith(\"groq/\"): return pill(f\"π’ {model.split('/')[1][:20]}\", \"pg\")\n if model.startswith(\"openai/\"): return pill(\"π€ GPT-3.5\", \"pb\")\n if \"wiki\" in src: return pill(\"π Wikipedia\", \"py\")\n return pill(\"π Context\", \"ps\")\ndef spill(src):\n return pill(\"π Textbook\", \"pp\") if \"textbook\" in src else pill(\"π Wikipedia\", \"py\")\n\n# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n# TOP BAR\n# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\nv = st.session_state.view\nidx = st.session_state.indexed\npage_labels = {\"upload\":\"π Upload & Index\",\"chat\":\"π¬ Chat\",\"sources\":\"π Sources & PDF\"}\nllm_badge = (pill(\"π’ Groq\",\"pg\") if has_groq\n else pill(\"π€ OpenAI\",\"pb\") if has_openai\n else pill(\"β No LLM\",\"py\"))\nidx_badge = pill(\"β Indexed\",\"pg\") if idx else pill(\"β Not Indexed\",\"ps\")\n\nst.markdown(f\"\"\"\n
\n\"\"\", unsafe_allow_html=True)\n\n# ββ Hamburger toggle ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n# FIX: marker div so CSS :has() can target ONLY the hamburger stHorizontalBlock\n# (not the upload columns), avoiding the :first-of-type collision bug\nst.markdown(\n '',\n unsafe_allow_html=True,\n)\nhamb_col = st.columns([1, 20])[0]\nwith hamb_col:\n hamb_label = \"β\" if st.session_state.sidebar_open else \"β°\"\n if st.button(hamb_label, key=\"hamburger\"):\n st.session_state.sidebar_open = not st.session_state.sidebar_open\n st.rerun()\n\nst.markdown(f\"\"\"\n\n\"\"\", unsafe_allow_html=True)\n\n\n\n# ββ Sidebar overlay ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n# ββ Sidebar overlay ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nif st.session_state.sidebar_open:\n\n cur = st.session_state.theme\n\n SWATCH_DATA = [\n (\"dark\", \"\\U0001f535\", \"Dark\"),\n (\"light\", \"\\u2b1c\", \"Light\"),\n (\"indigo\", \"\\U0001f7e3\", \"Indigo\"),\n (\"teal\", \"\\U0001f7e2\", \"Teal\"),\n (\"rose\", \"\\U0001f534\", \"Rose\"),\n (\"amber\", \"\\U0001f7e0\", \"Amber\"),\n (\"mono\", \"\\u26ab\", \"Mono\"),\n ]\n _theme_list = list(t for t, *_ in SWATCH_DATA)\n _active_i = _theme_list.index(cur) + 1 # 1-based nth-child\n\n st.markdown('', unsafe_allow_html=True)\n\n st.markdown(f\"\"\"\n\n\n\"\"\", unsafe_allow_html=True)\n\n # ββ Widget layer ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n with st.container():\n st.markdown('', unsafe_allow_html=True)\n\n # Small top gap so content doesn't touch the very top of the panel\n st.markdown('', unsafe_allow_html=True)\n\n # Navigation\n st.markdown('Navigation', unsafe_allow_html=True)\n st.markdown('Drop any PDF β algorithms, CS, math, science β and ResolvaBot will extract, chunk, and index it for AI-powered Q&A.
\n