Spaces:
Configuration error
Configuration error
| import gradio as gr | |
| from Client.mcp_client import MCPClientExcelRAG | |
| from test import run_agent # ← import agent entry point | |
| import subprocess | |
| import sys | |
| import time | |
| subprocess.Popen([sys.executable, "-m", "Server.mcp_server"]) | |
| time.sleep(5) | |
| # Initialize MCP client | |
| client = MCPClientExcelRAG() | |
| client.start() | |
| # --- Supported scope for intent/planner --- | |
| SUPPORTED_IITS = ["IIT Bombay", "IIT Delhi", "IIT Madras"] | |
| SUPPORTED_BRANCHES = ["CSE", "ECE", "Mechanical", "Electrical", "Engineering Design"] | |
| YEARS = ["2024", "2025"] | |
| # --- Core ask: writes into selected session and returns messages twice --- | |
| ''' | |
| def ask(history, question, top_k, temperature, sessions, selected_name): | |
| history = history or [] | |
| sessions = sessions or [] | |
| selected_name = selected_name or (sessions[-1]["name"] if sessions else None) | |
| if not question or not question.strip(): | |
| history.append({"role": "assistant", "content": "⚠️ Please enter a question."}) | |
| # also update the current session if exists | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| s["messages"] = history | |
| break | |
| return history, history, sessions | |
| # Append user message | |
| history.append({"role": "user", "content": question}) | |
| # Agent call: intent → plan → call MCP tools → synthesize | |
| try: | |
| final_answer = run_agent( | |
| user_q=question, | |
| mcp_client=client, | |
| available_iits=SUPPORTED_IITS, | |
| available_branches=SUPPORTED_BRANCHES, | |
| years=YEARS, | |
| top_k=int(top_k), | |
| temperature=float(temperature), | |
| ) | |
| except Exception as e: | |
| final_answer = f"❌ Error while processing your request: {str(e)}" | |
| # Append assistant message | |
| history.append({"role": "assistant", "content": final_answer}) | |
| # Persist into the selected session | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| s["messages"] = history | |
| break | |
| return history, history, sessions | |
| ''' | |
| def ask(history, question, top_k, temperature, sessions, selected_name): | |
| history = history or [] | |
| sessions = sessions or [] | |
| selected_name = selected_name or (sessions[-1]["name"] if sessions else None) | |
| if not question or not question.strip(): | |
| history.append({"role": "assistant", "content": "⚠️ Please enter a question."}) | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| s["messages"] = history | |
| break | |
| return history, history, sessions | |
| # Append user message to visible chat | |
| history.append({"role": "user", "content": question}) | |
| # --- NEW: gather full session conversation for context --- | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| session_messages = s.get("messages", []) | |
| # include current question | |
| conversation = session_messages + [{"role": "user", "content": question}] | |
| break | |
| else: | |
| conversation = history.copy() | |
| # Call the agent (NOW conversation-aware) | |
| try: | |
| final_answer = run_agent( | |
| user_q=question, | |
| mcp_client=client, | |
| available_iits=SUPPORTED_IITS, | |
| available_branches=SUPPORTED_BRANCHES, | |
| years=YEARS, | |
| conversation=conversation, # <-- PASS HISTORY | |
| top_k=int(top_k), | |
| temperature=float(temperature), | |
| ) | |
| except Exception as e: | |
| final_answer = f"❌ Error while processing your request: {str(e)}" | |
| # Append assistant reply and persist to session | |
| history.append({"role": "assistant", "content": final_answer}) | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| s["messages"] = history | |
| break | |
| return history, history, sessions | |
| def clear_chat(): | |
| return [], [] | |
| # --- New chat: create session, clear history, select it in dropdown --- | |
| def new_chat_fn(history, sessions, selected_name): | |
| sessions = sessions or [] | |
| new_idx = len(sessions) + 1 | |
| new_name = f"Chat {new_idx}" | |
| sessions.append({"name": new_name, "messages": []}) | |
| # Clear current chat view and select the new one | |
| dropdown_update = gr.update(choices=[s["name"] for s in sessions], value=new_name) | |
| return [], [], sessions, dropdown_update | |
| # --- Load selected session into Chatbot --- | |
| def load_session_fn(sessions, selected_name): | |
| sessions = sessions or [] | |
| selected_name = selected_name or None | |
| messages = [] | |
| if selected_name: | |
| for s in sessions: | |
| if s["name"] == selected_name: | |
| messages = s.get("messages", []) | |
| break | |
| # Return messages -> Chatbot and State (keep them in sync) | |
| return messages, messages | |
| with gr.Blocks() as demo: | |
| # (your CSS and layout remain unchanged) | |
| gr.HTML(""" | |
| <style> | |
| /* Hide footer */ | |
| footer { | |
| display: none !important; | |
| } | |
| body, .gradio-container { background-color:#000 !important; color:#fff !important; } | |
| .left-panel { background:#0d0d0d !important; padding:15px; border-right:1px solid #222; min-height:100vh; } | |
| .left-panel * { color:#707070 !important; } | |
| /* ------------------------------ | |
| FIX 1: Top-K & Temperature labels → black | |
| ---------------------------------*/ | |
| #top-k-wrapper label, | |
| #top-k-wrapper .gr-form-label, | |
| #top-k-wrapper .title, | |
| #top-k-wrapper span, | |
| #top-k-wrapper .gr-slider-value, | |
| #temperature-wrapper label, | |
| #temperature-wrapper .gr-form-label, | |
| #temperature-wrapper .title, | |
| #temperature-wrapper span, | |
| #temperature-wrapper .gr-slider-value { | |
| color: #000 !important; | |
| } | |
| /* ------------------------------ | |
| FIX 2: Top-K & Temp reset (↺) icon → black | |
| ---------------------------------*/ | |
| #top-k-wrapper button[aria-label="reset"] *, | |
| #temperature-wrapper button[aria-label="reset"] * { | |
| color:#000 !important; | |
| fill:#000 !important; | |
| stroke:#000 !important; | |
| } | |
| /* ------------------------------ | |
| FIX 3: Slider min/max text (1,10 and 0,1) → black | |
| ---------------------------------*/ | |
| #top-k-wrapper .min-value, | |
| #top-k-wrapper .max-value, | |
| #temperature-wrapper .min-value, | |
| #temperature-wrapper .max-value { | |
| color:#000 !important; | |
| } | |
| /* ------------------------------ | |
| FIX 4: Dropdown selected text + dropdown menu list items → black | |
| ---------------------------------*/ | |
| #session-select *, | |
| #session-select .gr-dropdown, | |
| #session-select .gr-dropdown * { | |
| color:#000 !important; | |
| } | |
| /* Dropdown menu options */ | |
| .gradio-container .gr-dropdown ul li { | |
| color:#000 !important; | |
| } | |
| /* Make Top-K & Temperature labels black */ | |
| #top-k-wrapper .label, | |
| #top-k-wrapper .component-label, | |
| #top-k-wrapper label, | |
| #top-k-wrapper span.title, | |
| #temperature-wrapper .label, | |
| #temperature-wrapper .component-label, | |
| #temperature-wrapper label, | |
| #temperature-wrapper span.title { | |
| color: #000 !important; | |
| } | |
| /* Make min/max numbers black */ | |
| #top-k-wrapper .min-value, | |
| #top-k-wrapper .max-value, | |
| #temperature-wrapper .min-value, | |
| #temperature-wrapper .max-value { | |
| color: #000 !important; | |
| } | |
| /* Make reset (↺) icon completely black */ | |
| #top-k-wrapper button[aria-label="reset"] *, | |
| #temperature-wrapper button[aria-label="reset"] * { | |
| color:#000 !important; | |
| fill:#000 !important; | |
| stroke:#000 !important; | |
| } | |
| /* Text inside the numeric input boxes */ | |
| #top-k-wrapper input[type="number"], | |
| #temperature-wrapper input[type="number"] { | |
| color:#000 !important; | |
| background:#fff !important; | |
| border:1px solid #777 !important; | |
| } | |
| /* Ensure note-bar and its link are visibly white */ | |
| #note-bar, #note-bar * { color: #fff !important; } | |
| #note-bar a, | |
| #note-bar a:link, | |
| #note-bar a:visited, | |
| #note-bar a:hover, | |
| #note-bar a:active, | |
| .prose #note-bar a, | |
| .prose #note-bar a:link, | |
| .prose #note-bar a:visited, | |
| .prose #note-bar a:hover, | |
| .prose #note-bar a:active { | |
| color: #fff !important; | |
| text-decoration: underline !important; | |
| border-bottom: 1px solid rgba(255,255,255,0.6) !important; | |
| } | |
| .note-bar { font-size: 14px !important; margin-top: 8px !important; opacity: 0.95; } | |
| .note-text { | |
| color: white !important; | |
| } | |
| .note-text a { | |
| color: #87CEFA !important; /* optional: link color (light blue) */ | |
| } | |
| .note-text a:hover { | |
| text-decoration: underline; | |
| } | |
| .note-text, | |
| .note-text em { | |
| color: white !important; | |
| } | |
| .note-text a { | |
| color: #87CEFA !important; /* optional link color */ | |
| } | |
| .sidebar-title { font-size:22px; margin-bottom:10px; color:#fff !important; } | |
| .history-title { font-size:18px; margin-top:30px; margin-bottom:10px; color:#ccc !important; } | |
| #top-k-wrapper label, #top-k-wrapper .gr-form-label, #top-k-wrapper .title { color:#707070 !important; } | |
| #temperature-wrapper label, #temperature-wrapper .gr-form-label, #temperature-wrapper .title { color:#000 !important; } | |
| #top-k-wrapper .gradio-row, #top-k-wrapper .gr-form, | |
| #temperature-wrapper .gradio-row, #temperature-wrapper .gr-form { background: transparent !important; box-shadow:none !important; border:none !important; } | |
| #top-k-wrapper input[type="number"], #temperature-wrapper input[type="number"] { color:#707070 !important; background:#fff !important; border:1px solid #999 !important; } | |
| #question-box textarea { color:#000 !important; background:#fff !important; border:1px solid #999 !important; } | |
| button[aria-label="reset"], button[aria-label="clear"] { color:#000 !important; fill:#000 !important; border-color:#000 !important; background:#fff !important; } | |
| button[aria-label="reset"] svg, button[aria-label="clear"] svg { color:#000 !important; fill:#000 !important; stroke:#000 !important; } | |
| #new-chat-btn { color:#000 !important; background:#fff !important; border:1px solid #000 !important; } | |
| .chatbot { background:#111 !important; color:#707070 !important; } | |
| </style> | |
| """) | |
| # --- States --- | |
| history_messages = gr.State([]) # current chat messages | |
| sessions_state = gr.State([]) # [{"name": "Chat 1", "messages": [...]}, ...] | |
| selected_session = gr.State(None) # current dropdown selection | |
| with gr.Row(): | |
| # LEFT | |
| with gr.Column(scale=1, min_width=260, elem_classes="left-panel"): | |
| gr.Markdown("<div class='sidebar-title'>Chatbot</div>") | |
| new_chat_btn = gr.Button("➕ New Chat", elem_id="new-chat-btn") | |
| gr.Markdown("<div class='history-title'>Chat History</div>") | |
| session_select = gr.Dropdown(choices=[], label=None, interactive=True, elem_id="session-select") | |
| with gr.Group(elem_id="top-k-wrapper"): | |
| top_k = gr.Slider(1, 10, value=5, step=1, label="Top-K") | |
| with gr.Group(elem_id="temperature-wrapper"): | |
| temperature = gr.Slider(0.0, 1.0, value=0.1, step=0.1, label="Temperature") | |
| # RIGHT | |
| with gr.Column(scale=3): | |
| chatbot = gr.Chatbot(height=520, elem_classes=["chatbot"]) | |
| question = gr.Textbox(placeholder="Ask...", lines=2, show_label=False, elem_id="question-box") | |
| with gr.Row(): | |
| ask_btn = gr.Button("Ask") | |
| clear_btn = gr.Button("Clear") | |
| gr.Markdown( | |
| """ | |
| <div class="note-text"> | |
| ⚠️ <em>This is an agent just providing some recommendations.</em> | |
| For final decisions, please visit the official website:<br> | |
| https://josaa.admissions.nic.in/applicant/seatmatrix/openingclosingrankarchieve.aspx | |
| JoSAA Opening & Closing Ranks | |
| </a> | |
| </div> | |
| """, | |
| elem_classes="note-text" | |
| ) | |
| # Events | |
| ask_btn.click( | |
| ask, | |
| inputs=[history_messages, question, top_k, temperature, sessions_state, session_select], | |
| outputs=[chatbot, history_messages, sessions_state] | |
| ) | |
| question.submit( | |
| ask, | |
| inputs=[history_messages, question, top_k, temperature, sessions_state, session_select], | |
| outputs=[chatbot, history_messages, sessions_state] | |
| ) | |
| clear_btn.click(clear_chat, None, [chatbot, history_messages]) | |
| new_chat_btn.click( | |
| new_chat_fn, | |
| inputs=[history_messages, sessions_state, session_select], | |
| outputs=[chatbot, history_messages, sessions_state, session_select] | |
| ) | |
| session_select.change( | |
| load_session_fn, | |
| inputs=[sessions_state, session_select], | |
| outputs=[chatbot, history_messages] | |
| ) | |
| demo.launch() | |