seawolf2357 commited on
Commit
1df496d
ยท
verified ยท
1 Parent(s): dd8a0c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -147
app.py CHANGED
@@ -6,7 +6,7 @@ import os
6
  # ============================================
7
  # MiniMax-M2.1 Streaming Chat
8
  # Dual Provider: Novita (HF) + MiniMax Official API
9
- # Comic Classic Theme
10
  # ============================================
11
 
12
  # Provider ์ƒํƒœ ๊ด€๋ฆฌ
@@ -79,7 +79,7 @@ def chat_with_minimax(messages):
79
  def chat_respond(message, history):
80
  """
81
  Streaming chat with automatic fallback
82
- Returns: tuple (history, status)
83
  """
84
  if not message.strip():
85
  return history, provider.get_status()
@@ -90,25 +90,26 @@ def chat_respond(message, history):
90
  "content": "You are MiniMax-M2.1, a helpful AI assistant built by MiniMax. You excel at coding, tool use, and complex reasoning tasks. Respond in the same language as the user."
91
  }]
92
 
93
- # Add history
94
  for h in history:
95
- if isinstance(h, (list, tuple)) and len(h) == 2:
96
- if h[0]:
97
- api_messages.append({"role": "user", "content": h[0]})
98
- if h[1]:
99
- api_messages.append({"role": "assistant", "content": h[1]})
100
 
101
  api_messages.append({"role": "user", "content": message})
102
 
103
  response_text = ""
104
- current_status = provider.get_status()
105
 
106
  # 1์ฐจ: Novita
107
  if provider.novita_available and provider.current_provider == "novita":
108
  try:
109
  for chunk in chat_with_novita(api_messages):
110
  response_text += chunk
111
- yield history + [[message, response_text]], "๐ŸŸข Novita (HuggingFace)"
 
 
 
 
 
112
  return
113
  except Exception as e:
114
  error_msg = str(e).lower()
@@ -121,18 +122,30 @@ def chat_respond(message, history):
121
  # 2์ฐจ: MiniMax
122
  try:
123
  if not os.environ.get("MINIMAX_API_KEY"):
124
- yield history + [[message, "โŒ MINIMAX_API_KEY not configured."]], "๐Ÿ”ด No API Key"
 
 
 
 
125
  return
126
 
127
  for chunk in chat_with_minimax(api_messages):
128
  response_text += chunk
129
- yield history + [[message, response_text]], "๐ŸŸก MiniMax Official API"
 
 
 
 
130
  return
131
 
132
  except Exception as e:
133
  if "rate limit" not in str(e).lower():
134
  provider.reset_to_novita()
135
- yield history + [[message, f"โŒ Error: {str(e)}"]], "๐Ÿ”ด Error"
 
 
 
 
136
 
137
  def reset_provider_fn():
138
  """์ˆ˜๋™์œผ๋กœ Novita๋กœ ๋ฆฌ์…‹"""
@@ -147,10 +160,8 @@ def clear_chat_fn():
147
  # ๐ŸŽจ Comic Classic Theme CSS
148
  # ============================================
149
  css = """
150
- /* ===== ๐ŸŽจ Google Fonts Import ===== */
151
  @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@400;700&display=swap');
152
 
153
- /* ===== ๐ŸŽจ Comic Classic ๋ฐฐ๊ฒฝ ===== */
154
  .gradio-container {
155
  background-color: #FEF9C3 !important;
156
  background-image: radial-gradient(#1F2937 1px, transparent 1px) !important;
@@ -159,82 +170,40 @@ css = """
159
  font-family: 'Comic Neue', cursive, sans-serif !important;
160
  }
161
 
162
- /* ===== ํ—ˆ๊น…ํŽ˜์ด์Šค ํ—ค๋” ์ˆจ๊น€ ===== */
163
- .huggingface-space-header,
164
- #space-header,
165
- .space-header,
166
- [class*="space-header"],
167
- .svelte-1ed2p3z,
168
- .space-header-badge,
169
- [data-testid="space-header"] {
170
  display: none !important;
171
- visibility: hidden !important;
172
- height: 0 !important;
173
- width: 0 !important;
174
  }
175
 
176
- /* ===== Footer ์ˆจ๊น€ ===== */
177
- footer,
178
- .footer,
179
- .gradio-container footer,
180
- .built-with,
181
- [class*="footer"],
182
- .gradio-footer,
183
- .show-api,
184
- .built-with-gradio {
185
  display: none !important;
186
- visibility: hidden !important;
187
- height: 0 !important;
188
  }
189
 
190
- /* ===== ๐ŸŽจ ํ—ค๋” ํƒ€์ดํ‹€ ===== */
191
  .header-text h1 {
192
  font-family: 'Bangers', cursive !important;
193
  color: #1F2937 !important;
194
  font-size: 3.5rem !important;
195
- font-weight: 400 !important;
196
  text-align: center !important;
197
- margin-bottom: 0.5rem !important;
198
- text-shadow:
199
- 4px 4px 0px #FACC15,
200
- 6px 6px 0px #1F2937 !important;
201
  letter-spacing: 3px !important;
202
  -webkit-text-stroke: 2px #1F2937 !important;
203
  }
204
 
205
- /* ===== ๐ŸŽจ ์„œ๋ธŒํƒ€์ดํ‹€ ===== */
206
  .subtitle {
207
  text-align: center !important;
208
  font-family: 'Comic Neue', cursive !important;
209
  font-size: 1.2rem !important;
210
  color: #1F2937 !important;
211
- margin-bottom: 1.5rem !important;
212
  font-weight: 700 !important;
213
  }
214
 
215
- /* ===== ๐ŸŽจ ์นด๋“œ/ํŒจ๋„ ===== */
216
- .gr-panel,
217
- .gr-box,
218
- .gr-form,
219
- .block,
220
- .gr-group {
221
  background: #FFFFFF !important;
222
  border: 3px solid #1F2937 !important;
223
  border-radius: 8px !important;
224
  box-shadow: 6px 6px 0px #1F2937 !important;
225
- transition: all 0.2s ease !important;
226
  }
227
 
228
- .gr-panel:hover,
229
- .block:hover {
230
- transform: translate(-2px, -2px) !important;
231
- box-shadow: 8px 8px 0px #1F2937 !important;
232
- }
233
-
234
- /* ===== ๐ŸŽจ ์ž…๋ ฅ ํ•„๋“œ ===== */
235
- textarea,
236
- input[type="text"],
237
- input[type="number"] {
238
  background: #FFFFFF !important;
239
  border: 3px solid #1F2937 !important;
240
  border-radius: 8px !important;
@@ -244,23 +213,18 @@ input[type="number"] {
244
  font-weight: 700 !important;
245
  }
246
 
247
- textarea:focus,
248
- input[type="text"]:focus {
249
  border-color: #3B82F6 !important;
250
  box-shadow: 4px 4px 0px #3B82F6 !important;
251
  outline: none !important;
252
  }
253
 
254
- /* ===== ๐ŸŽจ Primary ๋ฒ„ํŠผ ===== */
255
- .gr-button-primary,
256
- button.primary,
257
- .gr-button.primary {
258
  background: #3B82F6 !important;
259
  border: 3px solid #1F2937 !important;
260
  border-radius: 8px !important;
261
  color: #FFFFFF !important;
262
  font-family: 'Bangers', cursive !important;
263
- font-weight: 400 !important;
264
  font-size: 1.3rem !important;
265
  letter-spacing: 2px !important;
266
  padding: 14px 28px !important;
@@ -268,52 +232,35 @@ button.primary,
268
  text-shadow: 1px 1px 0px #1F2937 !important;
269
  }
270
 
271
- .gr-button-primary:hover,
272
- button.primary:hover {
273
  background: #2563EB !important;
274
  transform: translate(-2px, -2px) !important;
275
  box-shadow: 7px 7px 0px #1F2937 !important;
276
  }
277
 
278
- .gr-button-primary:active,
279
- button.primary:active {
280
- transform: translate(3px, 3px) !important;
281
- box-shadow: 2px 2px 0px #1F2937 !important;
282
- }
283
-
284
- /* ===== ๐ŸŽจ Secondary ๋ฒ„ํŠผ ===== */
285
- .gr-button-secondary,
286
- button.secondary {
287
  background: #EF4444 !important;
288
  border: 3px solid #1F2937 !important;
289
  border-radius: 8px !important;
290
  color: #FFFFFF !important;
291
  font-family: 'Bangers', cursive !important;
292
- font-weight: 400 !important;
293
  font-size: 1.1rem !important;
294
  box-shadow: 4px 4px 0px #1F2937 !important;
295
- text-shadow: 1px 1px 0px #1F2937 !important;
296
  }
297
 
298
- .gr-button-secondary:hover,
299
- button.secondary:hover {
300
  background: #DC2626 !important;
301
  transform: translate(-2px, -2px) !important;
302
- box-shadow: 6px 6px 0px #1F2937 !important;
303
  }
304
 
305
- /* ===== ๐ŸŽจ ๋กœ๊ทธ/์ƒํƒœ ์ถœ๋ ฅ ===== */
306
  .status-box textarea {
307
  background: #1F2937 !important;
308
  color: #10B981 !important;
309
  font-family: 'Courier New', monospace !important;
310
- font-size: 0.9rem !important;
311
  border: 3px solid #10B981 !important;
312
- border-radius: 8px !important;
313
  box-shadow: 4px 4px 0px #10B981 !important;
314
  }
315
 
316
- /* ===== ๐ŸŽจ ์•„์ฝ”๋””์–ธ ===== */
317
  .gr-accordion {
318
  background: #FACC15 !important;
319
  border: 3px solid #1F2937 !important;
@@ -321,7 +268,6 @@ button.secondary:hover {
321
  box-shadow: 4px 4px 0px #1F2937 !important;
322
  }
323
 
324
- /* ===== ๐ŸŽจ ์ฑ„ํŒ… ์˜์—ญ ===== */
325
  .chatbot {
326
  border: 3px solid #1F2937 !important;
327
  border-radius: 12px !important;
@@ -329,7 +275,6 @@ button.secondary:hover {
329
  background: #FFFFFF !important;
330
  }
331
 
332
- /* ===== ๐ŸŽจ ์ฝ”๋“œ ๋ธ”๋ก ===== */
333
  pre, code {
334
  background: #1F2937 !important;
335
  color: #10B981 !important;
@@ -338,59 +283,23 @@ pre, code {
338
  font-family: 'Courier New', monospace !important;
339
  }
340
 
341
- /* ===== ๐ŸŽจ ๋ผ๋ฒจ ===== */
342
- label,
343
- .gr-input-label,
344
- .gr-block-label {
345
- color: #1F2937 !important;
346
- font-family: 'Comic Neue', cursive !important;
347
- font-weight: 700 !important;
348
- }
349
-
350
- /* ===== ๐ŸŽจ ์Šคํฌ๋กค๋ฐ” ===== */
351
- ::-webkit-scrollbar {
352
- width: 12px;
353
- }
354
 
355
- ::-webkit-scrollbar-track {
356
- background: #FEF9C3;
357
- border: 2px solid #1F2937;
358
- }
359
-
360
- ::-webkit-scrollbar-thumb {
361
- background: #3B82F6;
362
- border: 2px solid #1F2937;
363
- }
364
-
365
- ::-webkit-scrollbar-thumb:hover {
366
- background: #EF4444;
367
- }
368
-
369
- /* ===== ๐ŸŽจ ์„ ํƒ ํ•˜์ด๋ผ์ดํŠธ ===== */
370
- ::selection {
371
- background: #FACC15;
372
- color: #1F2937;
373
- }
374
-
375
- /* ===== ๋ฐ˜์‘ํ˜• ===== */
376
  @media (max-width: 768px) {
377
- .header-text h1 {
378
- font-size: 2.2rem !important;
379
- text-shadow: 3px 3px 0px #FACC15, 4px 4px 0px #1F2937 !important;
380
- }
381
-
382
- .gr-button-primary,
383
- button.primary {
384
- padding: 12px 20px !important;
385
- font-size: 1.1rem !important;
386
- }
387
  }
388
  """
389
 
390
  # ============================================
391
- # Gradio Interface (gr.Blocks ์Šคํƒ€์ผ)
392
  # ============================================
393
- with gr.Blocks(fill_height=True, css=css) as demo:
 
 
 
394
 
395
  # HOME Badge
396
  gr.HTML("""
@@ -405,14 +314,8 @@ with gr.Blocks(fill_height=True, css=css) as demo:
405
  """)
406
 
407
  # Header Title
408
- gr.Markdown(
409
- """# ๐Ÿค– MINIMAX-M2.1 CHAT ๐Ÿ’ฌ""",
410
- elem_classes="header-text"
411
- )
412
-
413
- gr.Markdown(
414
- """<p class="subtitle">โšก Claude Sonnet 4.5 ์ˆ˜์ค€์˜ ์ฝ”๋”ฉ & ์—์ด์ „ํŠธ ์„ฑ๋Šฅ! 230B ํŒŒ๋ผ๋ฏธํ„ฐ ์˜คํ”ˆ์†Œ์Šค ๋ชจ๋ธ ๐Ÿš€</p>"""
415
- )
416
 
417
  # Model Info Box
418
  gr.HTML("""
@@ -440,7 +343,7 @@ with gr.Blocks(fill_height=True, css=css) as demo:
440
  )
441
  reset_btn = gr.Button("๐Ÿ”„ Reset", variant="secondary", scale=1)
442
 
443
- # Chatbot
444
  chatbot = gr.Chatbot(
445
  label="๐Ÿ’ฌ Chat",
446
  height=450,
@@ -524,4 +427,4 @@ MINIMAX_API_KEY
524
  reset_btn.click(reset_provider_fn, outputs=[provider_status])
525
 
526
  if __name__ == "__main__":
527
- demo.launch()
 
6
  # ============================================
7
  # MiniMax-M2.1 Streaming Chat
8
  # Dual Provider: Novita (HF) + MiniMax Official API
9
+ # Gradio 6.0 Compatible
10
  # ============================================
11
 
12
  # Provider ์ƒํƒœ ๊ด€๋ฆฌ
 
79
  def chat_respond(message, history):
80
  """
81
  Streaming chat with automatic fallback
82
+ Gradio 6.0 messages format: [{"role": "user/assistant", "content": "..."}]
83
  """
84
  if not message.strip():
85
  return history, provider.get_status()
 
90
  "content": "You are MiniMax-M2.1, a helpful AI assistant built by MiniMax. You excel at coding, tool use, and complex reasoning tasks. Respond in the same language as the user."
91
  }]
92
 
93
+ # Add history (Gradio 6.0 messages format)
94
  for h in history:
95
+ if isinstance(h, dict):
96
+ api_messages.append({"role": h.get("role", "user"), "content": h.get("content", "")})
 
 
 
97
 
98
  api_messages.append({"role": "user", "content": message})
99
 
100
  response_text = ""
 
101
 
102
  # 1์ฐจ: Novita
103
  if provider.novita_available and provider.current_provider == "novita":
104
  try:
105
  for chunk in chat_with_novita(api_messages):
106
  response_text += chunk
107
+ # Gradio 6.0 messages format
108
+ new_history = history + [
109
+ {"role": "user", "content": message},
110
+ {"role": "assistant", "content": response_text}
111
+ ]
112
+ yield new_history, "๐ŸŸข Novita (HuggingFace)"
113
  return
114
  except Exception as e:
115
  error_msg = str(e).lower()
 
122
  # 2์ฐจ: MiniMax
123
  try:
124
  if not os.environ.get("MINIMAX_API_KEY"):
125
+ new_history = history + [
126
+ {"role": "user", "content": message},
127
+ {"role": "assistant", "content": "โŒ MINIMAX_API_KEY not configured."}
128
+ ]
129
+ yield new_history, "๐Ÿ”ด No API Key"
130
  return
131
 
132
  for chunk in chat_with_minimax(api_messages):
133
  response_text += chunk
134
+ new_history = history + [
135
+ {"role": "user", "content": message},
136
+ {"role": "assistant", "content": response_text}
137
+ ]
138
+ yield new_history, "๐ŸŸก MiniMax Official API"
139
  return
140
 
141
  except Exception as e:
142
  if "rate limit" not in str(e).lower():
143
  provider.reset_to_novita()
144
+ new_history = history + [
145
+ {"role": "user", "content": message},
146
+ {"role": "assistant", "content": f"โŒ Error: {str(e)}"}
147
+ ]
148
+ yield new_history, "๐Ÿ”ด Error"
149
 
150
  def reset_provider_fn():
151
  """์ˆ˜๋™์œผ๋กœ Novita๋กœ ๋ฆฌ์…‹"""
 
160
  # ๐ŸŽจ Comic Classic Theme CSS
161
  # ============================================
162
  css = """
 
163
  @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@400;700&display=swap');
164
 
 
165
  .gradio-container {
166
  background-color: #FEF9C3 !important;
167
  background-image: radial-gradient(#1F2937 1px, transparent 1px) !important;
 
170
  font-family: 'Comic Neue', cursive, sans-serif !important;
171
  }
172
 
173
+ .huggingface-space-header, #space-header, .space-header, [class*="space-header"] {
 
 
 
 
 
 
 
174
  display: none !important;
 
 
 
175
  }
176
 
177
+ footer, .footer, .gradio-footer, .built-with-gradio {
 
 
 
 
 
 
 
 
178
  display: none !important;
 
 
179
  }
180
 
 
181
  .header-text h1 {
182
  font-family: 'Bangers', cursive !important;
183
  color: #1F2937 !important;
184
  font-size: 3.5rem !important;
 
185
  text-align: center !important;
186
+ text-shadow: 4px 4px 0px #FACC15, 6px 6px 0px #1F2937 !important;
 
 
 
187
  letter-spacing: 3px !important;
188
  -webkit-text-stroke: 2px #1F2937 !important;
189
  }
190
 
 
191
  .subtitle {
192
  text-align: center !important;
193
  font-family: 'Comic Neue', cursive !important;
194
  font-size: 1.2rem !important;
195
  color: #1F2937 !important;
 
196
  font-weight: 700 !important;
197
  }
198
 
199
+ .gr-panel, .gr-box, .block, .gr-group {
 
 
 
 
 
200
  background: #FFFFFF !important;
201
  border: 3px solid #1F2937 !important;
202
  border-radius: 8px !important;
203
  box-shadow: 6px 6px 0px #1F2937 !important;
 
204
  }
205
 
206
+ textarea, input[type="text"] {
 
 
 
 
 
 
 
 
 
207
  background: #FFFFFF !important;
208
  border: 3px solid #1F2937 !important;
209
  border-radius: 8px !important;
 
213
  font-weight: 700 !important;
214
  }
215
 
216
+ textarea:focus, input[type="text"]:focus {
 
217
  border-color: #3B82F6 !important;
218
  box-shadow: 4px 4px 0px #3B82F6 !important;
219
  outline: none !important;
220
  }
221
 
222
+ .gr-button-primary, button.primary {
 
 
 
223
  background: #3B82F6 !important;
224
  border: 3px solid #1F2937 !important;
225
  border-radius: 8px !important;
226
  color: #FFFFFF !important;
227
  font-family: 'Bangers', cursive !important;
 
228
  font-size: 1.3rem !important;
229
  letter-spacing: 2px !important;
230
  padding: 14px 28px !important;
 
232
  text-shadow: 1px 1px 0px #1F2937 !important;
233
  }
234
 
235
+ .gr-button-primary:hover, button.primary:hover {
 
236
  background: #2563EB !important;
237
  transform: translate(-2px, -2px) !important;
238
  box-shadow: 7px 7px 0px #1F2937 !important;
239
  }
240
 
241
+ .gr-button-secondary, button.secondary {
 
 
 
 
 
 
 
 
242
  background: #EF4444 !important;
243
  border: 3px solid #1F2937 !important;
244
  border-radius: 8px !important;
245
  color: #FFFFFF !important;
246
  font-family: 'Bangers', cursive !important;
 
247
  font-size: 1.1rem !important;
248
  box-shadow: 4px 4px 0px #1F2937 !important;
 
249
  }
250
 
251
+ .gr-button-secondary:hover, button.secondary:hover {
 
252
  background: #DC2626 !important;
253
  transform: translate(-2px, -2px) !important;
 
254
  }
255
 
 
256
  .status-box textarea {
257
  background: #1F2937 !important;
258
  color: #10B981 !important;
259
  font-family: 'Courier New', monospace !important;
 
260
  border: 3px solid #10B981 !important;
 
261
  box-shadow: 4px 4px 0px #10B981 !important;
262
  }
263
 
 
264
  .gr-accordion {
265
  background: #FACC15 !important;
266
  border: 3px solid #1F2937 !important;
 
268
  box-shadow: 4px 4px 0px #1F2937 !important;
269
  }
270
 
 
271
  .chatbot {
272
  border: 3px solid #1F2937 !important;
273
  border-radius: 12px !important;
 
275
  background: #FFFFFF !important;
276
  }
277
 
 
278
  pre, code {
279
  background: #1F2937 !important;
280
  color: #10B981 !important;
 
283
  font-family: 'Courier New', monospace !important;
284
  }
285
 
286
+ ::-webkit-scrollbar { width: 12px; }
287
+ ::-webkit-scrollbar-track { background: #FEF9C3; border: 2px solid #1F2937; }
288
+ ::-webkit-scrollbar-thumb { background: #3B82F6; border: 2px solid #1F2937; }
289
+ ::-webkit-scrollbar-thumb:hover { background: #EF4444; }
 
 
 
 
 
 
 
 
 
290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  @media (max-width: 768px) {
292
+ .header-text h1 { font-size: 2.2rem !important; }
 
 
 
 
 
 
 
 
 
293
  }
294
  """
295
 
296
  # ============================================
297
+ # Gradio Interface (Gradio 6.0 Compatible)
298
  # ============================================
299
+ with gr.Blocks(fill_height=True) as demo:
300
+
301
+ # Inject CSS via HTML
302
+ gr.HTML(f"<style>{css}</style>")
303
 
304
  # HOME Badge
305
  gr.HTML("""
 
314
  """)
315
 
316
  # Header Title
317
+ gr.Markdown("""# ๐Ÿค– MINIMAX-M2.1 CHAT ๐Ÿ’ฌ""", elem_classes="header-text")
318
+ gr.Markdown("""<p class="subtitle">โšก Claude Sonnet 4.5 ์ˆ˜์ค€์˜ ์ฝ”๋”ฉ & ์—์ด์ „ํŠธ ์„ฑ๋Šฅ! 230B ํŒŒ๋ผ๋ฏธํ„ฐ ์˜คํ”ˆ์†Œ์Šค ๋ชจ๋ธ ๐Ÿš€</p>""")
 
 
 
 
 
 
319
 
320
  # Model Info Box
321
  gr.HTML("""
 
343
  )
344
  reset_btn = gr.Button("๐Ÿ”„ Reset", variant="secondary", scale=1)
345
 
346
+ # Chatbot - Gradio 6.0 uses messages format by default
347
  chatbot = gr.Chatbot(
348
  label="๐Ÿ’ฌ Chat",
349
  height=450,
 
427
  reset_btn.click(reset_provider_fn, outputs=[provider_status])
428
 
429
  if __name__ == "__main__":
430
+ demo.launch(ssr_mode=False)