|
import gradio as gr |
|
import modelscope_studio.components.antd as antd |
|
import modelscope_studio.components.antdx as antdx |
|
import modelscope_studio.components.base as ms |
|
import modelscope_studio.components.pro as pro |
|
from modelscope_studio.components.pro.chatbot import ( |
|
ChatbotBotConfig, ChatbotPromptsConfig, ChatbotUserConfig, ChatbotWelcomeConfig) |
|
|
|
MODEL_NAME = 'AlpDroid' |
|
LOGO_URL = "https://raw.githubusercontent.com/yourusername/alpdroid/main/logo.png" |
|
|
|
|
|
DEFAULT_PROMPTS = [ |
|
{"title": "💻 Kod Yaz", "description": "Python kodu yazma konusunda yardım et"}, |
|
{"title": "🤖 AI Açıkla", "description": "Yapay zeka konularını basit şekilde açıkla"}, |
|
{"title": "📚 Öğren", "description": "Yeni bir konu öğrenmek istiyorum"}, |
|
{"title": "🔧 Problem Çöz", "description": "Teknik bir problemi çözmeye yardım et"} |
|
] |
|
|
|
|
|
EXAMPLES = { |
|
"Web Uygulamaları": [ |
|
{"title": "Todo App", "description": "Basit bir yapılacaklar listesi uygulaması"}, |
|
{"title": "Hesap Makinesi", "description": "JavaScript hesap makinesi"}, |
|
{"title": "Hava Durumu", "description": "Hava durumu gösterici widget"} |
|
], |
|
"Oyunlar": [ |
|
{"title": "Snake Oyunu", "description": "Klasik yılan oyunu"}, |
|
{"title": "Memory Oyunu", "description": "Hafıza kartları oyunu"}, |
|
{"title": "Tic Tac Toe", "description": "XOX oyunu"} |
|
] |
|
} |
|
|
|
def clear(): |
|
return gr.update(value=None) |
|
|
|
def submit(sender_value, chatbot_value): |
|
if sender_value is not None: |
|
chatbot_value.append({ |
|
"role": "user", |
|
"content": sender_value, |
|
}) |
|
|
|
chatbot_value.append({ |
|
"role": "assistant", |
|
"content": "Düşünüyorum...", |
|
"loading": True, |
|
"status": "pending" |
|
}) |
|
|
|
yield { |
|
sender: gr.update(value=None, loading=True), |
|
clear_btn: gr.update(disabled=True), |
|
chatbot: gr.update(value=chatbot_value) |
|
} |
|
|
|
try: |
|
|
|
time.sleep(2) |
|
|
|
chatbot_value[-1]["content"] = "Bu bir test yanıtıdır. Gerçek API entegrasyonu için API_URL ve API_KEY değerlerini ayarlayın." |
|
chatbot_value[-1]["loading"] = False |
|
chatbot_value[-1]["status"] = "done" |
|
chatbot_value[-1]["footer"] = "2.00s" |
|
|
|
yield { |
|
clear_btn: gr.update(disabled=False), |
|
sender: gr.update(loading=False), |
|
chatbot: gr.update(value=chatbot_value), |
|
} |
|
|
|
except Exception as e: |
|
chatbot_value[-1]["loading"] = False |
|
chatbot_value[-1]["status"] = "done" |
|
chatbot_value[-1]["content"] = "Bir hata oluştu, lütfen tekrar deneyin." |
|
yield { |
|
clear_btn: gr.update(disabled=False), |
|
sender: gr.update(loading=False), |
|
chatbot: gr.update(value=chatbot_value), |
|
} |
|
|
|
def generate_code(query: str): |
|
if not query: |
|
return { |
|
code_output: gr.update(value=""), |
|
sandbox: gr.update(value=""), |
|
state_tab: gr.update(active_key="empty") |
|
} |
|
|
|
|
|
yield { |
|
code_output: gr.update(value="Kod üretiliyor..."), |
|
sandbox: gr.update(value=""), |
|
state_tab: gr.update(active_key="loading") |
|
} |
|
|
|
time.sleep(3) |
|
|
|
|
|
sample_code = f"""<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>{query}</title> |
|
<style> |
|
body {{ |
|
font-family: Arial, sans-serif; |
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
color: white; |
|
padding: 20px; |
|
text-align: center; |
|
}} |
|
.container {{ |
|
background: rgba(255,255,255,0.1); |
|
padding: 30px; |
|
border-radius: 15px; |
|
max-width: 600px; |
|
margin: 50px auto; |
|
}} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<h1>AlpDroid tarafından üretildi</h1> |
|
<p>İstek: {query}</p> |
|
<p>Bu basit bir örnek HTML kodu. Gerçek API entegrasyonu için kodu düzenleyin.</p> |
|
</div> |
|
</body> |
|
</html>""" |
|
|
|
encoded_html = base64.b64encode(sample_code.encode('utf-8')).decode('utf-8') |
|
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}" |
|
iframe = f'<iframe src="{data_uri}" width="100%" height="500px" sandbox="allow-scripts"></iframe>' |
|
|
|
yield { |
|
code_output: gr.update(value=f"```html\n{sample_code}\n```"), |
|
sandbox: gr.update(value=iframe), |
|
state_tab: gr.update(active_key="render") |
|
} |
|
|
|
def select_example(example): |
|
if isinstance(example, dict): |
|
return example.get("description", "") |
|
return "" |
|
|
|
|
|
css = """ |
|
/* Purple Theme for AlpDroid */ |
|
:root { |
|
--primary-color: #8B5CF6; |
|
--secondary-color: #A78BFA; |
|
--background: #1F1B24; |
|
--surface: #2D2438; |
|
--text-primary: #FFFFFF; |
|
--text-secondary: #C4B5FD; |
|
} |
|
|
|
.gradio-container { |
|
background: var(--background) !important; |
|
} |
|
|
|
/* Chat interface styling */ |
|
.ant-tabs-tab { |
|
color: var(--text-secondary) !important; |
|
} |
|
|
|
.ant-tabs-tab-active { |
|
color: var(--primary-color) !important; |
|
} |
|
|
|
/* Button styling */ |
|
.ant-btn-primary { |
|
background: var(--primary-color) !important; |
|
border-color: var(--primary-color) !important; |
|
} |
|
|
|
.ant-btn-primary:hover { |
|
background: var(--secondary-color) !important; |
|
border-color: var(--secondary-color) !important; |
|
} |
|
|
|
/* Input styling */ |
|
.ant-input, .ant-input-textarea { |
|
background: var(--surface) !important; |
|
border-color: var(--secondary-color) !important; |
|
color: var(--text-primary) !important; |
|
} |
|
|
|
/* Card styling */ |
|
.ant-card { |
|
background: var(--surface) !important; |
|
border-color: var(--secondary-color) !important; |
|
} |
|
|
|
.ant-card-head-title { |
|
color: var(--text-primary) !important; |
|
} |
|
|
|
/* Example cards */ |
|
.example-card { |
|
background: var(--surface) !important; |
|
border: 1px solid var(--secondary-color) !important; |
|
border-radius: 12px; |
|
margin: 8px; |
|
transition: all 0.3s ease; |
|
} |
|
|
|
.example-card:hover { |
|
transform: translateY(-2px); |
|
box-shadow: 0 8px 25px rgba(139, 92, 246, 0.3) !important; |
|
border-color: var(--primary-color) !important; |
|
} |
|
|
|
.example-card .ant-card-meta-title { |
|
color: var(--text-primary) !important; |
|
font-weight: 600; |
|
} |
|
|
|
.example-card .ant-card-meta-description { |
|
color: var(--text-secondary) !important; |
|
} |
|
|
|
/* Output container */ |
|
.output-container { |
|
background: var(--surface) !important; |
|
border-radius: 12px; |
|
min-height: 500px; |
|
} |
|
|
|
.output-empty { |
|
color: var(--text-secondary) !important; |
|
} |
|
|
|
/* Loading spinner */ |
|
.ant-spin-text { |
|
color: var(--text-secondary) !important; |
|
} |
|
|
|
/* Iframe container */ |
|
.output-html iframe { |
|
border-radius: 8px; |
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2); |
|
} |
|
|
|
/* Scrollbar */ |
|
::-webkit-scrollbar { |
|
width: 8px; |
|
} |
|
|
|
::-webkit-scrollbar-track { |
|
background: var(--surface); |
|
} |
|
|
|
::-webkit-scrollbar-thumb { |
|
background: var(--primary-color); |
|
border-radius: 4px; |
|
} |
|
|
|
::-webkit-scrollbar-thumb:hover { |
|
background: var(--secondary-color); |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks(css=css, theme=gr.themes.Base()) as demo, ms.Application(), antdx.XProvider(): |
|
with antd.Tabs() as tabs: |
|
|
|
with antd.Tabs.Item(key="chat", label="💬 AlpDroid Chat"): |
|
with antd.Flex(vertical=True, gap="middle", elem_style={"height": "80vh"}): |
|
chatbot = pro.Chatbot( |
|
elem_style={"flex": 1, "maxHeight": "600px"}, |
|
welcome_config=ChatbotWelcomeConfig( |
|
variant="borderless", |
|
icon=LOGO_URL, |
|
title="Merhaba, Ben AlpDroid! 🤖", |
|
description="Size nasıl yardımcı olabilirim?", |
|
prompts=ChatbotPromptsConfig( |
|
title="Bugün size nasıl yardımcı olabilirim?", |
|
items=DEFAULT_PROMPTS |
|
) |
|
), |
|
user_config=ChatbotUserConfig(actions=["copy"]), |
|
bot_config=ChatbotBotConfig( |
|
header=MODEL_NAME, |
|
avatar=LOGO_URL, |
|
actions=["copy"] |
|
) |
|
) |
|
|
|
with antdx.Sender() as sender: |
|
with ms.Slot("prefix"): |
|
with antd.Button(color="default", variant="text") as clear_btn: |
|
with ms.Slot("icon"): |
|
antd.Icon("ClearOutlined") |
|
|
|
|
|
with antd.Tabs.Item(key="code", label="💻 Kod Playground"): |
|
with antd.Row(gutter=[24, 16]): |
|
with antd.Col(span=24, md=12): |
|
with antd.Card(title="📝 Kod Talep Et"): |
|
code_input = antd.Input.Textarea( |
|
size="large", |
|
placeholder="Ne tür bir uygulama istiyorsunuz? (örn: Todo listesi, hesap makinesi)", |
|
auto_size={"minRows": 3, "maxRows": 6} |
|
) |
|
|
|
with antd.Flex(gap="small", elem_style={"marginTop": "16px"}): |
|
code_btn = antd.Button("🚀 Kod Üret", type="primary", size="large") |
|
|
|
code_output = ms.Markdown(elem_style={"marginTop": "16px", "maxHeight": "300px", "overflow": "auto"}) |
|
|
|
|
|
with antd.Card(title="💡 Örnekler", elem_style={"marginTop": "16px"}): |
|
with antd.Tabs() as example_tabs: |
|
for category, examples in EXAMPLES.items(): |
|
with antd.Tabs.Item(key=category, label=category): |
|
with antd.Flex(gap="small", wrap=True): |
|
for example in examples: |
|
with antd.Card(elem_classes="example-card", hoverable=True) as example_card: |
|
antd.Card.Meta( |
|
title=example['title'], |
|
description=example['description'] |
|
) |
|
|
|
example_card.click( |
|
fn=select_example, |
|
inputs=[gr.State(example)], |
|
outputs=[code_input] |
|
) |
|
|
|
with antd.Col(span=24, md=12): |
|
with antd.Card(title="🎯 Sonuç", elem_classes="output-container"): |
|
with antd.Tabs(active_key="empty", render_tab_bar="() => null") as state_tab: |
|
with antd.Tabs.Item(key="empty"): |
|
antd.Empty( |
|
description="Kod üretmek için talebinizi girin", |
|
elem_classes="output-empty" |
|
) |
|
with antd.Tabs.Item(key="loading"): |
|
antd.Spin(True, tip="Kod üretiliyor...", size="large") |
|
with antd.Tabs.Item(key="render"): |
|
sandbox = gr.HTML() |
|
|
|
|
|
clear_btn.click(fn=clear, outputs=[chatbot]) |
|
|
|
submit_event = sender.submit( |
|
fn=submit, |
|
inputs=[sender, chatbot], |
|
outputs=[sender, chatbot, clear_btn] |
|
) |
|
|
|
code_btn.click( |
|
fn=generate_code, |
|
inputs=[code_input], |
|
outputs=[code_output, sandbox, state_tab] |
|
) |
|
|
|
if __name__ == '__main__': |
|
demo.queue().launch( |
|
server_name="0.0.0.0", |
|
server_port=7860, |
|
share=True |
|
) |