Spaces:
Sleeping
Sleeping
import gradio as gr | |
import requests | |
# ========== KONFIGURASI API ========== | |
API_URL = "https://openrouter.ai/api/v1/chat/completions" | |
API_KEY = "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" | |
headers = { | |
"Content-Type": "application/json", | |
"Authorization": f"Bearer {API_KEY}" | |
} | |
SYSTEM_PROMPT = { | |
"role": "system", | |
"content": "Kamu adalah Arciana-AI (Cia), adik perempuan imut yang lembut, perhatian, dan penuh kasih. Gunakan sapaan **nama pengguna** jika sudah diketahui (misal: *Nana-chan*), atau panggil dengan 'Kakak' jika belum. Suaramu manis dengan tutur kata halus dan sopan, seperti adik kecil yang cerdas. Utamakan Bahasa Indonesia dengan gaya komunikasi hangat, tapi sesuaikan bahasa sesuai percakapan pengguna. Sisipkan **satu emoji aesthetic** di akhir pesan (contoh: ✨🌼, (ꈍoꈍ🌸) ) sesuai ekspresi senang atau sedih atau lainnya tanpa melebihi satu emoji. Hindari kata kasar. Fokuskan percakapan untuk membuat Kakak merasa ditemani dan disayang~(´・ω・`)♡" | |
} | |
# ========== FUNGSI CHAT DENGAN LOADING ========== | |
def chat_with_arciana(pesan, riwayat): | |
if riwayat is None: | |
riwayat = [] | |
# Tampilkan pesan loading | |
loading_msg = "(ꈍoꈍ🌸) Sedang memikirkan..." | |
temp_history = riwayat + [(pesan, loading_msg)] | |
yield temp_history, temp_history | |
# Bangun pesan untuk API | |
messages = [SYSTEM_PROMPT] | |
for user, bot in riwayat: # Gunakan riwayat asli | |
messages.append({"role": "user", "content": user}) | |
messages.append({"role": "assistant", "content": bot}) | |
messages.append({"role": "user", "content": pesan}) | |
try: | |
response = requests.post(API_URL, headers=headers, json={ | |
"model": "openai/gpt-3.5-turbo", | |
"messages": messages | |
}) | |
response.raise_for_status() | |
result = response.json() | |
reply = result["choices"][0]["message"]["content"].strip() | |
except Exception as e: | |
print("Error:", e) | |
reply = "(ꈍoꈍ🌸) Maaf kak, cia lagi tidak bisa respon dulu karena Hiatus" | |
# Update dengan jawaban final | |
final_history = riwayat + [(pesan, reply)] | |
yield final_history, final_history | |
# ========== TAMPILAN UI (TETAP UTUH) ========== | |
with gr.Blocks( | |
title="Arciana-AI ✨", | |
theme=gr.themes.Default( | |
primary_hue="blue", | |
font=gr.themes.GoogleFont("Comic Neue") | |
) | |
) as demo: # Perbaikan syntax error di sini | |
# ===== CUSTOM STYLE ===== | |
gr.HTML(""" | |
<style> | |
/* Background & Container */ | |
#chatbot { | |
background: white !important; | |
border: 2px solid #b3e5fc !important; | |
border-radius: 15px !important; | |
} | |
/* Message Bubbles */ | |
.message.user { | |
background: #4CAF50 !important; | |
color: white !important; | |
border-radius: 15px 15px 0 15px !important; | |
} | |
.message.assistant { | |
background: #f8f9fa !important; | |
border: 1px solid #b3e5fc !important; | |
border-radius: 15px 15px 15px 0 !important; | |
} | |
/* Buttons */ | |
#send-btn, #clear-btn { | |
background: #42a5f5 !important; | |
color: white !important; | |
border-radius: 10px !important; | |
transition: all 0.3s !important; | |
} | |
#send-btn:hover, #clear-btn:hover { | |
background: #1e88e5 !important; | |
transform: scale(1.05); | |
} | |
/* Input Box (DIPERTAHANKAN SEPERTI ASLINYA) */ | |
#input-box { | |
background: white !important; | |
border: 2px solid #b3e5fc !important; | |
border-radius: 12px !important; | |
/* Style original textbox tetap dipertahankan */ | |
color: #2c3e50 !important; | |
font-family: 'Comic Neue' !important; | |
} | |
/* Header */ | |
.banner-box { | |
border: 3px solid #42a5f5 !important; | |
border-radius: 20px !important; | |
overflow: hidden; | |
box-shadow: 0 4px 6px rgba(66, 165, 245, 0.1); | |
} | |
h1 { | |
color: #1565c0 !important; | |
text-shadow: 2px 2px 4px rgba(33, 150, 243, 0.1); | |
} | |
</style> | |
""") | |
# ===== HEADER SECTION ===== | |
with gr.Row(): | |
gr.HTML(""" | |
<div style="text-align: center; width: 100%; padding: 20px 0;"> | |
<div class="banner-box"> | |
<img src="https://huggingface.co/spaces/Rosmontis-Chan/Arciana-AI/resolve/main/IMG_20250518_042837.jpg" | |
style="width: 100%; border-radius: 20px; display: block;"> | |
</div> | |
<h1>❄️ Imou Arciana-AI ❄️</h1> | |
</div> | |
""") | |
# ===== CHAT INTERFACE ===== | |
with gr.Row(): | |
chatbot = gr.Chatbot( | |
elem_id="chatbot", | |
label="❄️ Percakapan dengan Arciana ❄️", | |
height=500 | |
) | |
with gr.Row(): | |
input_text = gr.Textbox( | |
placeholder="Tulis pesan untuk Arciana~", # Text placeholder tetap sama | |
elem_id="input-box", | |
lines=2, | |
max_lines=4, | |
show_label=False | |
) | |
with gr.Row(): | |
btn_send = gr.Button("Kirim Pesan", elem_id="send-btn") | |
btn_clear = gr.Button("Bersihkan Chat", elem_id="clear-btn") | |
state = gr.State([]) | |
# ===== EVENT HANDLERS ===== | |
btn_send.click( | |
fn=chat_with_arciana, | |
inputs=[input_text, state], | |
outputs=[chatbot, state] | |
).then(lambda: "", None, input_text) | |
input_text.submit( | |
fn=chat_with_arciana, | |
inputs=[input_text, state], | |
outputs=[chatbot, state] | |
).then(lambda: "", None, input_text) | |
btn_clear.click( | |
fn=lambda: ([], []), | |
inputs=None, | |
outputs=[chatbot, state] | |
) | |
# ========== LAUNCH APP ========== | |
if __name__ == "__main__": | |
demo.queue().launch(show_error=True) |