File size: 3,325 Bytes
4a35942
4a7d211
4a35942
fea6201
 
54e32c3
1dad43b
1e24c34
e632292
 
1e24c34
fea6201
4a35942
074fe2f
4a35942
 
fea6201
4a35942
 
 
074fe2f
1e24c34
4a35942
fea6201
 
 
 
 
 
 
e632292
4a7d211
fea6201
 
 
 
 
1e24c34
fea6201
 
 
 
 
 
 
 
 
 
 
 
 
4a35942
54e32c3
fea6201
 
1dad43b
a9c0001
fea6201
1dad43b
 
fea6201
 
 
 
 
a9c0001
fea6201
a9c0001
 
1dad43b
fea6201
a9c0001
1dad43b
e632292
54e32c3
fea6201
 
 
bf01995
4a35942
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
import os
import requests
import gradio as gr
import time
from markdown import markdown

# 🔑 Gemini API key
gemini_api_key = os.getenv("GEMINI_API_KEY")
if gemini_api_key is None:
    raise ValueError("⚠️ GEMINI_API_KEY тохируулаагүй байна!")

# Gemini API call
def gemini_response(prompt):
    try:
        url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={gemini_api_key}"
        headers = {"Content-Type": "application/json"}
        data = {"contents":[{"parts":[{"text":prompt}]}]}
        res = requests.post(url, headers=headers, json=data)
        res_json = res.json()
        return res_json["candidates"][0]["content"]["parts"][0]["text"]
    except Exception as e:
        return f"⚠️ Gemini error: {e}"

# Chat function with typing effect + markdown rendering
def chat(prompt, history=[], theme="Dark"):
    history.append((f"🧑 {prompt}", None))
    time.sleep(0.5)  # simulate typing
    reply_raw = gemini_response(prompt)
    reply_md = markdown(f"🤖 {reply_raw}")
    history[-1] = (history[-1][0], reply_md)
    return history, history

# OAuth placeholder (Google login)
def oauth_login():
    return "✅ Logged in (Google OAuth placeholder)"

# CSS for premium UI + theme + animations
css = """
.gradio-container {font-family: 'Segoe UI', sans-serif;}
textarea, input {border-radius:15px; padding:10px;}
button {border-radius:15px; padding:10px 20px; font-weight:bold;}
.gradio-chatbot-message.user {background-color:#0f2c54; color:#fff; border-radius:20px; padding:12px; margin:5px 0; transition: transform 0.2s;}
.gradio-chatbot-message.user:hover {transform: scale(1.02);}
.gradio-chatbot-message.bot {background-color:#1f1f1f; color:#00d9ff; border-radius:20px; padding:12px; margin:5px 0; transition: transform 0.2s;}
.gradio-chatbot-message.bot:hover {transform: scale(1.02);}
.chat-header {display:flex; align-items:center; gap:10px; justify-content: space-between;}
.chat-header img {height:50px; width:50px; border-radius:12px;}
.menu {display:flex; gap:15px; align-items:center;}
.loader {border:4px solid #f3f3f3; border-top:4px solid #00d9ff; border-radius:50%; width:20px; height:20px; animation: spin 1s linear infinite;}
@keyframes spin {100% {transform: rotate(360deg);}}
.scrollable-card {max-height:200px; overflow-y:auto; border:1px solid #444; border-radius:10px; padding:10px; margin:5px 0; background-color:#1a1a1a; color:#00d9ff;}
"""

# Logo path
logo_path = "logo.png"  # upload to Space

with gr.Blocks(css=css, theme=gr.themes.Soft()) as app:
    # Header
    with gr.Row(elem_classes="chat-header"):
        gr.Image(value=logo_path, show_label=False)
        gr.Markdown("## ZeppFusion AI")
        with gr.Row(elem_classes="menu"):
            theme_btn = gr.Dropdown(["Dark","Light"], value="Dark", label="Theme")
            login_btn = gr.Button("Login with Google")
    
    chatbot = gr.Chatbot()
    msg = gr.Textbox(placeholder="Таны асуулт...", lines=1)
    clear = gr.Button("🗑️ Clear History")

    # Submit chat
    msg.submit(chat, [msg, chatbot, theme_btn], [chatbot, chatbot])
    
    # Clear chat history
    clear.click(lambda: [], None, chatbot)

    # OAuth login
    login_btn.click(oauth_login, None, None)

if __name__ == "__main__":
    app.launch()