File size: 8,085 Bytes
9fed5eb 6c0a77b 9fed5eb a6a5b95 0fa4c35 2ac9925 4fbea5c 2ac9925 cd5bf3e 941fa74 0e39519 a6a5b95 0e39519 37b3a8f 46f400d a6a5b95 6c0a77b a6a5b95 da25f45 63915c5 da25f45 ffc7824 46f400d 8a57409 941fa74 2ac9925 4be4d09 941fa74 089b085 46f400d 63915c5 da25f45 9fed5eb f2c648d 9fed5eb 0e39519 ffc7824 0e39519 9fed5eb 63915c5 941fa74 f2c648d 089b085 f2c648d 089b085 877bbfe 2ac9925 970247f c9c51e1 8a57409 0e39519 8a57409 089b085 f2c648d 0e39519 46f400d da25f45 46f400d aeaba38 0e39519 970247f 089b085 ab36099 63915c5 0e39519 ffc7824 0e39519 da25f45 0e39519 9202bce 6c0a77b 941fa74 c69f3d8 3da4140 6c0a77b ab36099 6c0a77b 3da4140 c69f3d8 941fa74 a6a5b95 63915c5 0e39519 941fa74 0e39519 acfb71e 0e39519 9fed5eb 0e39519 9fed5eb f2c648d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | import os
import gradio as gr
from groq import Groq
# 1. Setup API Client
api_key = os.environ.get("GROQ_API_KEY")
client = Groq(api_key=api_key)
# 2. UI Styling
custom_css = """
/* Standard Layout */
.gradio-container {
max-width: 100% !important;
height: 95vh !important;
margin: 0 !important;
padding: 10px 20px !important;
}
#chatbot-window {
height: 70vh !important;
border-radius: 12px;
border: 1px solid #e0e0e0;
background: white;
}
/* --- MOBILE RESPONSIVE LOGIC --- */
@media (max-width: 768px) {
.gradio-container {
padding: 5px !important;
height: auto !important;
}
#chatbot-window {
height: 60vh !important;
}
.sidebar-panel {
min-width: 100% !important;
margin-top: 20px;
}
h1 { font-size: 1.5rem !important; }
}
/* Dark Mode Overrides */
.dark #chatbot-window {
background: #1a1a1a !important;
border-color: #444 !important;
}
#system-prompt-container textarea, .scroll-input textarea {
height: 45px !important;
max-height: 45px !important;
overflow-y: auto !important;
resize: none !important;
}
#settings-btn {
width: 44px !important;
height: 44px !important;
min-width: 44px !important;
border-radius: 8px !important;
background: #f0f0f0 !important;
border: 1px solid #ddd !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 20px !important;
cursor: pointer !important;
}
.sidebar-panel {
background-color: #f9f9f9;
padding: 15px !important;
border-radius: 12px;
border: 1px solid #ddd;
min-width: 300px !important;
}
.dark .sidebar-panel {
background-color: #2d2d2d !important;
border-color: #444 !important;
}
"""
# 3. Secure Chat Logic
def chat_with_groq(message, history, model, temperature, system_prompt):
cleaned_messages = [{"role": "system", "content": system_prompt}]
for msg in history:
cleaned_messages.append({"role": msg["role"], "content": msg["content"]})
cleaned_messages.append({"role": "user", "content": message})
try:
response = client.chat.completions.create(
model=model,
messages=cleaned_messages,
temperature=temperature,
stream=True
)
partial_message = ""
for chunk in response:
if chunk.choices[0].delta.content:
partial_message += chunk.choices[0].delta.content
yield partial_message
except Exception as e:
yield f"โ ๏ธ API Error: {str(e)}"
def toggle_dark_mode(current_is_dark):
new_state = not current_is_dark
new_label = "โ๏ธ Light Mode" if new_state else "๐ Dark Mode"
return new_label, new_state
toggle_dark_js = """() => { document.body.classList.toggle('dark'); }"""
# 4. Interface Setup
with gr.Blocks() as demo:
sidebar_state = gr.State(False)
dark_state = gr.State(False)
# Header Section
with gr.Row():
with gr.Column(scale=20):
gr.Markdown("# ๐ค SageBot | *Developed by Hassan Naseer*")
with gr.Column(scale=1, min_width=50):
settings_btn = gr.Button("โ๏ธ", elem_id="settings-btn")
with gr.Row():
# Main Chat Area
with gr.Column(scale=4) as chat_col:
chatbot = gr.Chatbot(elem_id="chatbot-window")
with gr.Row():
msg_input = gr.Textbox(
placeholder="Ask me anything...",
container=False,
scale=9,
elem_classes="scroll-input"
)
submit_btn = gr.Button("Send", variant="primary", scale=1, min_width=80)
# Sidebar Area
with gr.Column(scale=1, visible=False, elem_classes="sidebar-panel") as sidebar_col:
dark_btn = gr.Button("๐ Dark Mode", variant="secondary")
model_choice = gr.Dropdown(
choices=["llama-3.3-70b-versatile", "llama-3.1-8b-instant"],
value="llama-3.3-70b-versatile", label="Select Model"
)
temp = gr.Slider(0.0, 1.0, 0.7, label="Temperature")
sys_msg = gr.Textbox(
value="You are a professional assistant.",
label="System Prompt",
lines=1,
elem_id="system-prompt-container"
)
# Re-added Support Section with full SVG Icons
gr.HTML("""
<div style="text-align: center; margin-top: 20px; padding-top: 15px; border-top: 1px solid #ddd;">
<p style="font-size: 0.85em; color: #555; margin-bottom: 12px;">Connect with the developer</p>
<div style="display: flex; justify-content: center; gap: 20px; align-items: center;">
<a href="https://www.linkedin.com/in/hassan-naseer-web-developer" target="_blank">
<svg width="28" height="28" viewBox="0 0 24 24" fill="#0077b5">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.239-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/>
</svg>
</a>
<a href="https://wa.me/923099702809" target="_blank">
<svg width="55" height="55" viewBox="0 0 24 24" fill="#25D366">
<path d="M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766 0-3.18-2.587-5.771-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.299.045-.677.063-1.092-.069-.252-.08-.575-.187-.988-.365-1.739-.751-2.874-2.502-2.961-2.617-.087-.116-.708-.94-.708-1.793 0-.852.448-1.271.607-1.442.159-.171.348-.214.464-.214.116 0 .232.001.333.006.101.005.237-.038.37.284.144.35.493 1.203.536 1.29.043.087.072.188.014.304-.058.116-.087.188-.174.289-.087.101-.184.225-.261.304-.093.097-.19.202-.082.387.108.185.479.791 1.029 1.282.709.633 1.308.83 1.493.922.185.093.294.077.404-.051.11-.128.471-.548.598-.736.127-.188.253-.159.426-.096.173.063 1.096.516 1.284.609.188.093.312.139.356.215.044.076.044.439-.1.844z"/>
</svg>
</a>
<a href="mailto:hk4960498@gmail.com" target="_blank">
<svg width="28" height="28" viewBox="0 0 24 24" fill="#555">
<path d="M0 3v18h24v-18h-24zm21.518 2l-9.518 7.713-9.518-7.713h19.036zm-19.518 14v-11.817l10 8.104 10-8.104v11.817h-20z"/>
</svg>
</a>
</div>
</div>
""")
# --- Events ---
settings_btn.click(lambda s: (gr.update(visible=not s), not s), [sidebar_state], [sidebar_col, sidebar_state])
dark_btn.click(toggle_dark_mode, [dark_state], [dark_btn, dark_state], js=toggle_dark_js)
def user_turn(msg, hist):
if not msg: return "", hist
hist.append({"role": "user", "content": msg})
return "", hist
def bot_turn(hist, m, t, s):
user_msg = hist[-1]["content"]
gen = chat_with_groq(user_msg, hist[:-1], m, t, s)
hist.append({"role": "assistant", "content": ""})
for chunk in gen:
hist[-1]["content"] = chunk
yield hist
msg_input.submit(user_turn, [msg_input, chatbot], [msg_input, chatbot], queue=False).then(
bot_turn, [chatbot, model_choice, temp, sys_msg], chatbot
)
submit_btn.click(user_turn, [msg_input, chatbot], [msg_input, chatbot], queue=False).then(
bot_turn, [chatbot, model_choice, temp, sys_msg], chatbot
)
if __name__ == "__main__":
demo.launch(css=custom_css) |