Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -189,3 +189,201 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
189 |
""")
|
190 |
|
191 |
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
""")
|
190 |
|
191 |
demo.launch()
|
192 |
+
|
193 |
+
import gradio as gr
|
194 |
+
import os
|
195 |
+
import requests
|
196 |
+
import time
|
197 |
+
|
198 |
+
# Daftar model dengan deskripsi
|
199 |
+
MODELS_INFO = {
|
200 |
+
"anthropic/claude-opus-4": {"name": "Claude Opus 4", "description": "Model AI paling canggih Anthropic untuk tugas kompleks"},
|
201 |
+
"anthropic/claude-sonnet-4": {"name": "Claude Sonnet 4", "description": "Keseimbangan antara kemampuan dan kecepatan"},
|
202 |
+
"deepseek/deepseek-r1-0528": {"name": "DeepSeek R1", "description": "Model bahasa open-source khusus untuk reasoning"},
|
203 |
+
"deepseek/deepseek-chat-v3-0324": {"name": "DeepSeek Chat v3", "description": "Dioptimalkan untuk dialog general"},
|
204 |
+
"openai/gpt-4.1": {"name": "GPT-4.1", "description": "Generasi penyusun teks OpenAI terbaru"},
|
205 |
+
"openai/gpt-4.1-mini": {"name": "GPT-4.1 Mini", "description": "Versi lebih kecil dan cepat dari GPT-4.1"},
|
206 |
+
"google/gemini-2.5-pro-preview": {"name": "Gemini 2.5 Pro", "description": "Model Google terbaru untuk pemahaman kompleks"},
|
207 |
+
"microsoft/phi-4-reasoning-plus": {"name": "Phi-4 Reasoning", "description": "Pakar penalaran matematika dan logika"},
|
208 |
+
"qwen/qwen3-30b-a3b": {"name": "Qwen 30B", "description": "Model bahasa besar dari China"},
|
209 |
+
"meta-llama/llama-guard-4-12b": {"name": "Llama Guard 4", "description": "Model khusus untuk moderasi konten"},
|
210 |
+
"meta-llama/llama-4-maverick": {"name": "Llama 4 Maverick", "description": "Model kreatif untuk penulisan"};
|
211 |
+
"meta-llama/llama-4-scout": {"name": "Llama 4 Scout", "description": "Direncanakan sebagai penerus Gemini ini"/>
|
212 |
+
"x-ai/grok-2-vision-1212": {"name": "Grok-2 Vision", "description": "Model multimodal X-AI untuk teks dan gambar"}}
|
213 |
+
}
|
214 |
+
|
215 |
+
# Default models list
|
216 |
+
MODELS = list(MODELS_INFO.keys())
|
217 |
+
|
218 |
+
def chat_with_openrouter(prompt, system_prompt, model):
|
219 |
+
try:
|
220 |
+
# Konfigurasi API OpenRouter
|
221 |
+
api_url = "https://openrouter.ai/api/v1/chat/completions"
|
222 |
+
api_key = os.environ.get("OPENROUTER_API_KEY")
|
223 |
+
|
224 |
+
# Header untuk autentikasi
|
225 |
+
headers = {
|
226 |
+
"Authorization": f"Bearer {api_key}",
|
227 |
+
"HTTP-Referer": "https://huggingface.co",
|
228 |
+
"X-Title": "OpenRouter Space",
|
229 |
+
}
|
230 |
+
|
231 |
+
# Bangun pesan dengan sistem prompt
|
232 |
+
messages = []
|
233 |
+
if system_prompt.strip():
|
234 |
+
messages.append({"role": "system", "content": system_prompt})
|
235 |
+
messages.append({"role": "user", "content": prompt})
|
236 |
+
|
237 |
+
# Body request
|
238 |
+
data = {
|
239 |
+
"model": model,
|
240 |
+
"messages": messages,
|
241 |
+
"max_tokens": 2048
|
242 |
+
}
|
243 |
+
|
244 |
+
start_time = time.time()
|
245 |
+
|
246 |
+
# Kirim request ke OpenRouter
|
247 |
+
response = requests.post(api_url, headers=headers, json=data, timeout=90)
|
248 |
+
response.raise_for_status()
|
249 |
+
|
250 |
+
# Ekstrak dan kembalikan respons
|
251 |
+
result = response.json()
|
252 |
+
|
253 |
+
end_time = time.time()
|
254 |
+
processing_time = f"\n\nπ Waktu pemrosesan: {end_time - start_time:.2f} detik"
|
255 |
+
|
256 |
+
return result["choices"][0]["message"]["content"] + processing_time
|
257 |
+
|
258 |
+
except Exception as e:
|
259 |
+
error_detail = f"{str(e)}"
|
260 |
+
if hasattr(e, 'response') and e.response:
|
261 |
+
try:
|
262 |
+
error_resp = e.response.json()
|
263 |
+
error_detail += f"\nError: {error_resp.get('error', {}).get('message', 'Unknown error')}"
|
264 |
+
except:
|
265 |
+
error_detail += f"\nStatus: {e.response.status_code}\nResponse: {e.response.text[:500]}"
|
266 |
+
return f"π¨ Error: {error_detail}"
|
267 |
+
|
268 |
+
# CSS Styles
|
269 |
+
with open("style.css", "r") as f:
|
270 |
+
css_content = f.read()
|
271 |
+
|
272 |
+
# Buat antarmuka Gradio dengan CSS
|
273 |
+
with gr.Blocks(css=css_content, theme=gr.themes.Soft()) as demo:
|
274 |
+
gr.Markdown("#app-container", visible=False)
|
275 |
+
|
276 |
+
# Header Section
|
277 |
+
with gr.Column(elem_classes="header"):
|
278 |
+
gr.Markdown("""
|
279 |
+
# π€ Advanced AI Chat Assistant
|
280 |
+
Eksplorasi model AI terbaik melalui OpenRouter
|
281 |
+
""")
|
282 |
+
|
283 |
+
# Main Content
|
284 |
+
with gr.Row(elem_classes="content"):
|
285 |
+
# Left Controls Panel
|
286 |
+
with gr.Column(elem_classes="controls"):
|
287 |
+
with gr.Group(elem_classes="model-selector"):
|
288 |
+
selected_model = gr.Dropdown(
|
289 |
+
label="Pilih Model AI",
|
290 |
+
choices=MODELS,
|
291 |
+
value="anthropic/claude-opus-4",
|
292 |
+
interactive=True,
|
293 |
+
elem_id="model-dropdown"
|
294 |
+
)
|
295 |
+
|
296 |
+
# Preview model info cards
|
297 |
+
with gr.Group():
|
298 |
+
gr.Markdown("### Info Model")
|
299 |
+
with gr.Row():
|
300 |
+
for model_id in MODELS:
|
301 |
+
info = MODELS_INFO[model_id]
|
302 |
+
with gr.Column(min_width=250):
|
303 |
+
card = gr.Checkbox(
|
304 |
+
label=f"**{info['name']}**\n{info['description']}",
|
305 |
+
value=(model_id == "anthropic/claude-opus-4"),
|
306 |
+
elem_classes="model-card",
|
307 |
+
elem_id=f"model-card-{model_id}"
|
308 |
+
)
|
309 |
+
card.change(lambda x,m=model_id: m, inputs=[card], outputs=[selected_model])
|
310 |
+
|
311 |
+
with gr.Group(elem_classes="system-prompt-area"):
|
312 |
+
system_prompt = gr.Textbox(
|
313 |
+
label="Sistem Prompt (Opsional)",
|
314 |
+
placeholder="Contoh: 'Anda adalah ahli bahasa Indonesia yang ramah dan membantu'",
|
315 |
+
lines=5,
|
316 |
+
max_lines=10
|
317 |
+
)
|
318 |
+
|
319 |
+
with gr.Group(elem_classes="tips"):
|
320 |
+
gr.Markdown("### π Tips Penggunaan")
|
321 |
+
gr.Markdown("""
|
322 |
+
- Claude Opus: Terbaik untuk tugas kompleks
|
323 |
+
- Gemini 2.5: Penalaran kuat dan detail
|
324 |
+
- GPT-4.1: Kreativi tinggi dan fleksibel
|
325 |
+
- Llama 4: Variasi fungsi khusus
|
326 |
+
- **Ctrl+Enter** untuk mengirim prompt
|
327 |
+
- Gunakan contoh di bawah untuk memulai
|
328 |
+
""")
|
329 |
+
|
330 |
+
# Right Chat Panel
|
331 |
+
with gr.Column(elem_classes="chat-container"):
|
332 |
+
with gr.Column(elem_classes="chat-area"):
|
333 |
+
with gr.Group(elem_classes="chat-input"):
|
334 |
+
prompt = gr.Textbox(
|
335 |
+
label="Pertanyaan/Permintaan",
|
336 |
+
placeholder="Tulis pesan untuk AI di sini...",
|
337 |
+
lines=6
|
338 |
+
)
|
339 |
+
with gr.Row():
|
340 |
+
clear_btn = gr.Button("Hapus")
|
341 |
+
submit_btn = gr.Button("Kirim ke AI", elem_classes="btn-submit")
|
342 |
+
|
343 |
+
with gr.Group(elem_classes="chat-output"):
|
344 |
+
output = gr.Textbox(
|
345 |
+
label="Respon AI",
|
346 |
+
lines=15,
|
347 |
+
interactive=False
|
348 |
+
)
|
349 |
+
|
350 |
+
# Kwamples Section
|
351 |
+
with gr.Group(elem_classes="examples"):
|
352 |
+
gr.Examples(
|
353 |
+
examples=[
|
354 |
+
["Terjemahkan artikel ilmiah ini ke bahasa Indonesia: [...teks ilmiah...]", "", "openai/gpt-4.1"],
|
355 |
+
["Tulis puisi tentang budaya Indonesia dalam gaya Chairil Anwar", "Pakai bahasa Indonesia dengan gaya puisi modern", "anthropic/claude-sonnet-4"],
|
356 |
+
["Jelaskan black hole dalam konsep relativitas umum secara sederhana", "Anda adalah profesor astrofisika yang ramah", "google/gemini-2.5-pro-preview"],
|
357 |
+
["Ubahlah kode ini menjadi lebih efisien: [contoh kode Python]", "Fokus pada penggunaan memori dan kompleksitas algoritma", "microsoft/phi-4-reasoning-plus"]
|
358 |
+
],
|
359 |
+
inputs=[prompt, system_prompt, selected_model],
|
360 |
+
label="Contoh Permintaan AI"
|
361 |
+
)
|
362 |
+
|
363 |
+
# Footer
|
364 |
+
with gr.Column(elem_classes="footer"):
|
365 |
+
gr.Markdown("""
|
366 |
+
### Dibangun dengan π€
|
367 |
+
Powered by [OpenRouter](https://openrouter.ai) |
|
368 |
+
[Sumber Daya API](https://openrouter.ai/docs) |
|
369 |
+
[Statistik Penggunaan](https://openrouter.ai/activity)
|
370 |
+
""")
|
371 |
+
gr.HTML("""<img src="https://cdn.myportfolio.com/45200424-090f-478b-9be0-85ca9dee2b39/f3a8a7fb-b385-4a7a-8bee-e325c4b9cf9b_rw_600.png?h=fe0a7278654a29de048391005c6d748f" width="200">""")
|
372 |
+
|
373 |
+
# Event handlers
|
374 |
+
submit_btn.click(
|
375 |
+
fn=chat_with_openrouter,
|
376 |
+
inputs=[prompt, system_prompt, selected_model],
|
377 |
+
outputs=output
|
378 |
+
)
|
379 |
+
|
380 |
+
clear_btn.click(lambda: ["", ""], outputs=[prompt, output])
|
381 |
+
|
382 |
+
prompt.submit(
|
383 |
+
fn=chat_with_openrouter,
|
384 |
+
inputs=[prompt, system_prompt, selected_model],
|
385 |
+
outputs=output
|
386 |
+
)
|
387 |
+
|
388 |
+
demo.launch()
|
389 |
+
|