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
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"}
]
# Simple examples for code playground
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:
# Simulate API call (replace with your actual API)
time.sleep(2) # Simulated thinking time
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")
}
# Simulate code generation
yield {
code_output: gr.update(value="Kod üretiliyor..."),
sandbox: gr.update(value=""),
state_tab: gr.update(active_key="loading")
}
time.sleep(3) # Simulate processing time
# Simple HTML example
sample_code = f"""
{query}
AlpDroid tarafından üretildi
İstek: {query}
Bu basit bir örnek HTML kodu. Gerçek API entegrasyonu için kodu düzenleyin.
"""
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''
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 ""
# Purple theme CSS
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);
}
"""
# Main interface
with gr.Blocks(css=css, theme=gr.themes.Base()) as demo, ms.Application(), antdx.XProvider():
with antd.Tabs() as tabs:
# Chat Tab
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")
# Code Playground Tab
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"})
# Examples
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()
# Event handlers
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
)