dzezzefezfz commited on
Commit
311a85a
·
verified ·
1 Parent(s): 19974cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +214 -11
app.py CHANGED
@@ -2,6 +2,9 @@ import os
2
  import requests
3
  import gradio as gr
4
 
 
 
 
5
  HF_API_KEY = os.environ.get("HF_API_KEY")
6
  if not HF_API_KEY:
7
  raise RuntimeError("HF_API_KEY is not set in Space variables")
@@ -24,25 +27,225 @@ def get_first_model():
24
 
25
  MODEL = get_first_model()
26
 
27
- def chat(message):
28
  payload = {
29
  "model": MODEL,
30
- "messages": [{"role": "user", "content": message}],
31
  "temperature": 0.7,
32
- "max_tokens": 200,
33
  }
34
-
35
  r = requests.post(f"{BASE_URL}/chat/completions", headers=HEADERS, json=payload, timeout=60)
36
  if r.status_code != 200:
37
  return f"HTTP {r.status_code}: {r.text}"
38
-
39
  data = r.json()
40
  return data["choices"][0]["message"]["content"]
41
 
42
- demo = gr.Interface(
43
- fn=chat,
44
- inputs=gr.Textbox(label=f"You (model: {MODEL})"),
45
- outputs=gr.Textbox(label="Bot"),
46
- title="My AI Chatbot",
47
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  demo.launch()
 
2
  import requests
3
  import gradio as gr
4
 
5
+ # -----------------------------
6
+ # Hugging Face Router (OpenAI-compatible)
7
+ # -----------------------------
8
  HF_API_KEY = os.environ.get("HF_API_KEY")
9
  if not HF_API_KEY:
10
  raise RuntimeError("HF_API_KEY is not set in Space variables")
 
27
 
28
  MODEL = get_first_model()
29
 
30
+ def call_model(messages):
31
  payload = {
32
  "model": MODEL,
33
+ "messages": messages,
34
  "temperature": 0.7,
35
+ "max_tokens": 250,
36
  }
 
37
  r = requests.post(f"{BASE_URL}/chat/completions", headers=HEADERS, json=payload, timeout=60)
38
  if r.status_code != 200:
39
  return f"HTTP {r.status_code}: {r.text}"
 
40
  data = r.json()
41
  return data["choices"][0]["message"]["content"]
42
 
43
+
44
+ # -----------------------------
45
+ # UI + Chat logic
46
+ # -----------------------------
47
+ def respond(user_msg, history):
48
+ history = history or []
49
+ # Convert Gradio history (list of [user, bot]) -> OpenAI-style messages
50
+ messages = [{"role": "system", "content": "You are a helpful assistant. Keep answers concise unless asked otherwise."}]
51
+ for u, b in history:
52
+ messages.append({"role": "user", "content": u})
53
+ messages.append({"role": "assistant", "content": b})
54
+
55
+ messages.append({"role": "user", "content": user_msg})
56
+ bot_msg = call_model(messages)
57
+
58
+ history.append([user_msg, bot_msg])
59
+ return "", history
60
+
61
+
62
+ # -----------------------------
63
+ # Modern CSS + theme toggle (light/dark)
64
+ # -----------------------------
65
+ CSS = """
66
+ :root{
67
+ --bg: #0b0f19;
68
+ --panel: rgba(255,255,255,0.06);
69
+ --panel-2: rgba(255,255,255,0.08);
70
+ --text: rgba(255,255,255,0.92);
71
+ --muted: rgba(255,255,255,0.68);
72
+ --border: rgba(255,255,255,0.12);
73
+ --accent: #7c3aed; /* purple */
74
+ --shadow: 0 10px 30px rgba(0,0,0,0.35);
75
+ }
76
+
77
+ body.light{
78
+ --bg: #f6f7fb;
79
+ --panel: rgba(0,0,0,0.04);
80
+ --panel-2: rgba(0,0,0,0.06);
81
+ --text: rgba(0,0,0,0.88);
82
+ --muted: rgba(0,0,0,0.60);
83
+ --border: rgba(0,0,0,0.10);
84
+ --accent: #2563eb; /* blue */
85
+ --shadow: 0 10px 30px rgba(0,0,0,0.10);
86
+ }
87
+
88
+ .gradio-container{
89
+ background: var(--bg) !important;
90
+ color: var(--text) !important;
91
+ }
92
+
93
+ #app_wrap{
94
+ max-width: 980px;
95
+ margin: 0 auto;
96
+ }
97
+
98
+ .card{
99
+ background: var(--panel);
100
+ border: 1px solid var(--border);
101
+ border-radius: 18px;
102
+ box-shadow: var(--shadow);
103
+ }
104
+
105
+ .header{
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ gap: 12px;
110
+ padding: 18px 18px 10px 18px;
111
+ }
112
+
113
+ .title{
114
+ font-size: 22px;
115
+ font-weight: 700;
116
+ letter-spacing: 0.2px;
117
+ }
118
+
119
+ .subtitle{
120
+ font-size: 13px;
121
+ color: var(--muted);
122
+ margin-top: 4px;
123
+ }
124
+
125
+ .badge{
126
+ padding: 6px 10px;
127
+ border-radius: 999px;
128
+ background: var(--panel-2);
129
+ border: 1px solid var(--border);
130
+ color: var(--muted);
131
+ font-size: 12px;
132
+ white-space: nowrap;
133
+ }
134
+
135
+ /* Chat area */
136
+ #chat{
137
+ border-top: 1px solid var(--border);
138
+ padding: 14px 14px 0 14px;
139
+ }
140
+
141
+ #chat .wrap{
142
+ border-radius: 16px;
143
+ }
144
+
145
+ /* Input row */
146
+ #input_row{
147
+ display: flex;
148
+ gap: 10px;
149
+ padding: 14px;
150
+ border-top: 1px solid var(--border);
151
+ }
152
+
153
+ #input_row textarea, #input_row input{
154
+ background: var(--panel-2) !important;
155
+ border: 1px solid var(--border) !important;
156
+ color: var(--text) !important;
157
+ border-radius: 14px !important;
158
+ }
159
+
160
+ button.primary{
161
+ background: var(--accent) !important;
162
+ border: none !important;
163
+ color: white !important;
164
+ border-radius: 14px !important;
165
+ }
166
+
167
+ button.secondary{
168
+ background: var(--panel-2) !important;
169
+ border: 1px solid var(--border) !important;
170
+ color: var(--text) !important;
171
+ border-radius: 14px !important;
172
+ }
173
+
174
+ /* Toggle */
175
+ .toggle{
176
+ display:flex;
177
+ align-items:center;
178
+ gap:10px;
179
+ user-select:none;
180
+ }
181
+
182
+ .toggle input{
183
+ width: 44px;
184
+ height: 24px;
185
+ }
186
+ """
187
+
188
+ THEME_TOGGLE_HTML = """
189
+ <div class="toggle">
190
+ <span style="color:var(--muted); font-size:13px;">Theme</span>
191
+ <label style="display:flex; align-items:center; gap:10px;">
192
+ <span style="color:var(--muted); font-size:13px;">Light</span>
193
+ <input id="themeToggle" type="checkbox" />
194
+ <span style="color:var(--muted); font-size:13px;">Dark</span>
195
+ </label>
196
+ </div>
197
+
198
+ <script>
199
+ // default to dark unless user saved preference
200
+ const saved = localStorage.getItem("theme") || "dark";
201
+ if (saved === "light") document.body.classList.add("light");
202
+ const toggle = document.getElementById("themeToggle");
203
+ // checked = dark
204
+ toggle.checked = (saved !== "light");
205
+
206
+ toggle.addEventListener("change", () => {
207
+ if (toggle.checked) {
208
+ document.body.classList.remove("light");
209
+ localStorage.setItem("theme", "dark");
210
+ } else {
211
+ document.body.classList.add("light");
212
+ localStorage.setItem("theme", "light");
213
+ }
214
+ });
215
+ </script>
216
+ """
217
+
218
+ with gr.Blocks(css=CSS, title="My AI Chatbot") as demo:
219
+ with gr.Column(elem_id="app_wrap"):
220
+ with gr.Group(elem_classes=["card"]):
221
+ with gr.Row(elem_classes=["header"]):
222
+ with gr.Column(scale=3):
223
+ gr.Markdown(f"""
224
+ <div class="title">My AI Chatbot</div>
225
+ <div class="subtitle">Modern UI • Light/Dark mode toggle • Running model: <span class="badge">{MODEL}</span></div>
226
+ """)
227
+ gr.HTML(THEME_TOGGLE_HTML)
228
+
229
+ chatbot = gr.Chatbot(
230
+ elem_id="chat",
231
+ height=520,
232
+ show_copy_button=True,
233
+ bubble_full_width=False,
234
+ )
235
+
236
+ with gr.Row(elem_id="input_row"):
237
+ msg = gr.Textbox(
238
+ placeholder="Type a message…",
239
+ show_label=False,
240
+ container=False,
241
+ scale=8,
242
+ )
243
+ send = gr.Button("Send", variant="primary", elem_classes=["primary"], scale=2)
244
+ clear = gr.Button("Clear", variant="secondary", elem_classes=["secondary"], scale=2)
245
+
246
+ # Wire events
247
+ send.click(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])
248
+ msg.submit(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])
249
+ clear.click(lambda: [], outputs=chatbot)
250
+
251
  demo.launch()