NeerajAhire's picture
Update chat_app.py
82ab1da verified
raw
history blame
13.1 kB
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()