NetPulse-AI / app.py
hashirehtisham's picture
Update app.py
1bc6ced verified
Raw
History Blame Contribute Delete
11.5 kB
import gradio as gr
from huggingface_hub import InferenceClient
import pandas as pd
# ── Constants ─────────────────────────────────────────────────────────────────
IMAGE_URL = "https://drive.google.com/uc?export=view&id=1OX1tj6gTNo8CkV9IDbNKgZ7WHvpNmgFo"
MODEL_ID = "microsoft/phi-4"
SYSTEM_MESSAGE = """\
You are a Fault Prediction Chatbot that analyzes network and system performance data \
to identify potential issues before they escalate. \
Based on the provided data, respond in the following format and must include the following headings:
# **Future Performance Prediction**
# **Risk Analysis and Potential Issues**
# **Preventive Actions and Recommendations**"""
SIMPLE_SYSTEM_MESSAGE = (
"You are an AI powered chatbot named as NetPulse-AI built by team HelixAI that provides "
"predictive maintenance insights, cost optimization suggestions, and energy efficiency "
"recommendations for networks."
)
css = """
footer {display:none !important}
.output-markdown{display:none !important}
.gr-button-primary {
z-index: 14; height: 43px; width: 130px; left: 0px; top: 0px; padding: 0px;
cursor: pointer !important;
background: none rgb(17, 20, 45) !important;
border: none !important; text-align: center !important;
font-family: Poppins !important; font-size: 14px !important;
font-weight: 500 !important; color: rgb(255, 255, 255) !important;
line-height: 1 !important; border-radius: 12px !important;
transition: box-shadow 200ms ease 0s, background 200ms ease 0s !important;
box-shadow: none !important;
}
.gr-button-primary:hover {
background: none rgb(66, 133, 244) !important;
box-shadow: rgb(0 0 0 / 23%) 0px 1px 7px 0px !important;
}
#image-container {
display: flex; justify-content: center;
align-items: center; height: auto; margin-top: 20px;
}
#compass-image { max-width: 800px; max-height: 600px; object-fit: contain; }
"""
# ── Helpers ───────────────────────────────────────────────────────────────────
def _build_messages(system_msg: str, history: list, message: str) -> list:
"""Convert Gradio history + new message into the HF messages format."""
msgs = [{"role": "system", "content": system_msg}]
for user_turn, bot_turn in history:
if user_turn:
msgs.append({"role": "user", "content": user_turn})
if bot_turn:
msgs.append({"role": "assistant", "content": bot_turn})
msgs.append({"role": "user", "content": message})
return msgs
def stream_chat(message, history, system_msg,
max_tokens, temperature, top_p,
hf_token: gr.OAuthToken):
"""
Generator that streams tokens back to the Gradio Chatbot component.
Yields the full updated history list on every token so Gradio can
re-render incrementally β€” this is true streaming with zero extra load.
"""
if not message:
yield history
return
if not hf_token:
yield history + [(message,
"⚠️ Please log in with your Hugging Face account (sidebar) before sending messages.")]
return
client = InferenceClient(model=MODEL_ID, token=hf_token.token)
messages = _build_messages(system_msg, history, message)
history = history + [(message, "")] # append placeholder
response = ""
for chunk in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
token = chunk.choices[0].delta.content or ""
response += token
history[-1] = (message, response) # update last turn in place
yield history
def save_history(history: list):
"""Serialise chatbot history to a .txt file for download."""
if not history:
return None
lines = []
for user_turn, bot_turn in history:
if user_turn:
lines.append(f"User: {user_turn}")
if bot_turn:
lines.append(f"Assistant: {bot_turn}\n")
path = "/tmp/chat_history.txt"
with open(path, "w", encoding="utf-8") as fh:
fh.write("\n".join(lines))
return path
def read_excel(file):
if file is None:
return ""
df = pd.read_excel(file.name)
return df.to_string()
# ── UI ────────────────────────────────────────────────────────────────────────
# FIX 1: css removed from gr.Blocks() β€” now passed to demo.launch() below
with gr.Blocks() as demo:
# ── Sidebar ───────────────────────────────────────────────────────────────
with gr.Sidebar():
gr.Markdown("### πŸ” Login")
gr.LoginButton()
gr.Markdown(
"Log in with your Hugging Face account to use NetPulse AI. "
"Your token is used only to call the inference API."
)
# ── Intro tab ─────────────────────────────────────────────────────────────
with gr.Tab("NetPulse AI"):
with gr.Row(elem_id="image-container"):
gr.Image(IMAGE_URL, elem_id="compass-image")
gr.Markdown("# **NetPulse AI**")
gr.Markdown("### **Developed by Team HELIX AI**")
gr.Markdown("""
**This project monitors network health using a Raspberry Pi, collecting data on CPU usage,
temperature, signal strength, and packet loss. The data is logged in Excel, identifying
abnormal conditions. Users upload the data to the chatbot for predictive analysis and
optimization recommendations.**
**Features:**
- **Future Performance Prediction:** Identifies upcoming failure risks based on past data trends.
- **Risk Analysis and Potential Issues:** Detects high-risk periods and network bottlenecks.
- **Preventive Actions and Recommendations:** Suggests cooling measures, bandwidth optimization, and maintenance alerts.
**How It Works:**
1. Log in with your Hugging Face account (sidebar).
2. Upload your Excel file in the *Upload Data* tab.
3. Paste the data into *Detailed Analysis* for a full report.
4. Use *General Chat* for follow-up questions.
""")
# ── Detailed Analysis tab ─────────────────────────────────────────────────
with gr.Tab("Detailed Analysis"):
gr.Markdown("# Detailed Analysis")
gr.Markdown(
"Analyze network performance trends, predict potential issues, and receive "
"tailored recommendations based on the uploaded data."
)
# FIX 2: show_copy_button removed β€” not supported in Gradio 6.0
chatbot_detail = gr.Chatbot(height=520)
msg_detail = gr.Textbox(label="Enter the Excel Copied Data here", lines=3)
with gr.Row():
clear_detail = gr.Button("New Chat")
download_btn = gr.Button("Download Chat History")
submit_detail = gr.Button("Submit", variant="primary")
download_out = gr.File(label="Download", visible=False)
with gr.Accordion("Advanced Settings", open=False):
max_tok_d = gr.Slider(1, 2048, 1024, step=1, label="Max new tokens")
temp_d = gr.Slider(0.1, 4.0, 0.7, step=0.1, label="Temperature")
top_p_d = gr.Slider(0.1, 1.0, 0.95, step=0.05, label="Top-p (nucleus sampling)")
sys_msg_detail = gr.Textbox(value=SYSTEM_MESSAGE, visible=False)
# Stream response, then clear input box
submit_detail.click(
stream_chat,
inputs=[msg_detail, chatbot_detail, sys_msg_detail,
max_tok_d, temp_d, top_p_d],
outputs=[chatbot_detail],
).then(
lambda: gr.update(value=""),
outputs=[msg_detail],
)
# Also allow Enter key to submit
msg_detail.submit(
stream_chat,
inputs=[msg_detail, chatbot_detail, sys_msg_detail,
max_tok_d, temp_d, top_p_d],
outputs=[chatbot_detail],
).then(
lambda: gr.update(value=""),
outputs=[msg_detail],
)
clear_detail.click(lambda: [], outputs=[chatbot_detail])
download_btn.click(
save_history,
inputs=[chatbot_detail],
outputs=[download_out],
).then(
lambda: gr.update(visible=True),
outputs=[download_out],
)
# ── Upload Data tab ───────────────────────────────────────────────────────
with gr.Tab("Upload Data"):
gr.Markdown("# Upload Data")
file_input = gr.File(label="Upload Excel file")
excel_output = gr.Textbox(label="Excel Content", lines=12, interactive=False)
file_input.change(read_excel, inputs=file_input, outputs=excel_output)
# ── General Chat tab ──────────────────────────────────────────────────────
with gr.Tab("General Chat for Network Optimization"):
gr.Markdown("# General Chat for Network Optimization")
gr.Markdown(
"Ask NetPulse AI for predictive maintenance insights, cost optimization "
"suggestions, and energy efficiency recommendations."
)
# FIX 2 (continued): show_copy_button removed here too
chatbot_simple = gr.Chatbot(height=520)
msg_simple = gr.Textbox(label="Type a message")
with gr.Row():
clear_simple = gr.Button("Clear")
submit_simple = gr.Button("Submit", variant="primary")
with gr.Accordion("Advanced Settings", open=False):
max_tok_s = gr.Slider(1, 2048, 1024, step=1, label="Max new tokens")
temp_s = gr.Slider(0.1, 4.0, 0.7, step=0.1, label="Temperature")
top_p_s = gr.Slider(0.1, 1.0, 0.95, step=0.05, label="Top-p (nucleus sampling)")
sys_msg_simple = gr.Textbox(value=SIMPLE_SYSTEM_MESSAGE, visible=False)
submit_simple.click(
stream_chat,
inputs=[msg_simple, chatbot_simple, sys_msg_simple,
max_tok_s, temp_s, top_p_s],
outputs=[chatbot_simple],
).then(
lambda: gr.update(value=""),
outputs=[msg_simple],
)
msg_simple.submit(
stream_chat,
inputs=[msg_simple, chatbot_simple, sys_msg_simple,
max_tok_s, temp_s, top_p_s],
outputs=[chatbot_simple],
).then(
lambda: gr.update(value=""),
outputs=[msg_simple],
)
clear_simple.click(lambda: [], outputs=[chatbot_simple])
# FIX 1 (continued): css now passed here instead of gr.Blocks()
demo.launch(css=css)