|
|
import gradio as gr |
|
|
from huggingface_hub import InferenceClient |
|
|
|
|
|
|
|
|
CUSTOM_CSS = """ |
|
|
/* Import terminal font */ |
|
|
@import url('https://fonts.googleapis.com/css2?family=VT323&family=JetBrains+Mono:wght@400;700&display=swap'); |
|
|
|
|
|
/* Main dark theme */ |
|
|
.gradio-container { |
|
|
background: #0a0a0a !important; |
|
|
font-family: 'JetBrains Mono', 'Courier New', monospace !important; |
|
|
} |
|
|
|
|
|
/* ASCII Header */ |
|
|
.ascii-header { |
|
|
display: flex !important; |
|
|
justify-content: center !important; |
|
|
padding: 1rem !important; |
|
|
background: #0a0a0a !important; |
|
|
border: 4px solid #0066ff !important; |
|
|
border-radius: 0 !important; |
|
|
margin-bottom: 1rem !important; |
|
|
overflow-x: auto !important; |
|
|
} |
|
|
|
|
|
.ascii-header pre { |
|
|
font-family: 'Courier New', Courier, monospace !important; |
|
|
font-size: 0.7rem !important; |
|
|
color: #00ffff !important; |
|
|
margin: 0 !important; |
|
|
line-height: 1.1 !important; |
|
|
text-shadow: 0 0 10px #00ffff, 0 0 20px #0066ff !important; |
|
|
text-align: left !important; |
|
|
} |
|
|
|
|
|
.subheader { |
|
|
font-family: 'VT323', monospace !important; |
|
|
color: #00aaff !important; |
|
|
text-align: center !important; |
|
|
font-size: 1.4rem !important; |
|
|
margin-bottom: 1.5rem !important; |
|
|
letter-spacing: 2px !important; |
|
|
} |
|
|
|
|
|
/* Chatbot container */ |
|
|
.chatbot-container { |
|
|
border: 4px solid #0066ff !important; |
|
|
border-radius: 0 !important; |
|
|
background: #0d0d0d !important; |
|
|
box-shadow: 0 0 30px rgba(0, 102, 255, 0.3), inset 0 0 60px rgba(0, 255, 255, 0.02) !important; |
|
|
} |
|
|
|
|
|
/* Chat messages */ |
|
|
.message { |
|
|
border-radius: 0 !important; |
|
|
border: 2px solid #004488 !important; |
|
|
margin: 8px !important; |
|
|
padding: 12px 16px !important; |
|
|
font-family: 'JetBrains Mono', monospace !important; |
|
|
} |
|
|
|
|
|
.user { |
|
|
background: #001a33 !important; |
|
|
border-color: #00aaff !important; |
|
|
border-left: 4px solid #00ffff !important; |
|
|
} |
|
|
|
|
|
.bot { |
|
|
background: #0d1a26 !important; |
|
|
border-color: #0066ff !important; |
|
|
border-left: 4px solid #0066ff !important; |
|
|
} |
|
|
|
|
|
/* Input textbox */ |
|
|
textarea, input[type="text"] { |
|
|
background: #0a0a0a !important; |
|
|
border: 3px solid #004488 !important; |
|
|
border-radius: 0 !important; |
|
|
color: #00ffff !important; |
|
|
font-family: 'JetBrains Mono', monospace !important; |
|
|
transition: all 0.3s ease !important; |
|
|
} |
|
|
|
|
|
textarea:focus, input[type="text"]:focus { |
|
|
border-color: #00aaff !important; |
|
|
box-shadow: 0 0 20px rgba(0, 170, 255, 0.5) !important; |
|
|
outline: none !important; |
|
|
} |
|
|
|
|
|
textarea::placeholder { |
|
|
color: #336699 !important; |
|
|
} |
|
|
|
|
|
/* Buttons */ |
|
|
button { |
|
|
background: #001a33 !important; |
|
|
border: 3px solid #0066ff !important; |
|
|
border-radius: 0 !important; |
|
|
color: #00ffff !important; |
|
|
font-family: 'JetBrains Mono', monospace !important; |
|
|
font-weight: 700 !important; |
|
|
padding: 10px 24px !important; |
|
|
transition: all 0.2s ease !important; |
|
|
text-transform: uppercase !important; |
|
|
letter-spacing: 2px !important; |
|
|
} |
|
|
|
|
|
button:hover { |
|
|
background: #0066ff !important; |
|
|
color: #000 !important; |
|
|
box-shadow: 0 0 20px rgba(0, 102, 255, 0.6) !important; |
|
|
} |
|
|
|
|
|
button.secondary { |
|
|
background: #0a0a0a !important; |
|
|
border: 3px solid #004488 !important; |
|
|
} |
|
|
|
|
|
/* Sliders */ |
|
|
input[type="range"] { |
|
|
accent-color: #00aaff !important; |
|
|
} |
|
|
|
|
|
.slider-container { |
|
|
background: #0d1a26 !important; |
|
|
border: 3px solid #004488 !important; |
|
|
border-radius: 0 !important; |
|
|
padding: 12px !important; |
|
|
} |
|
|
|
|
|
/* Labels */ |
|
|
label { |
|
|
color: #00aaff !important; |
|
|
font-family: 'JetBrains Mono', monospace !important; |
|
|
font-weight: 700 !important; |
|
|
text-transform: uppercase !important; |
|
|
font-size: 0.85rem !important; |
|
|
letter-spacing: 1px !important; |
|
|
} |
|
|
|
|
|
/* Sidebar */ |
|
|
.sidebar { |
|
|
background: #0a0a0a !important; |
|
|
border-right: 4px solid #0066ff !important; |
|
|
border-radius: 0 !important; |
|
|
} |
|
|
|
|
|
/* Accordion */ |
|
|
.accordion { |
|
|
background: #0d1a26 !important; |
|
|
border: 3px solid #004488 !important; |
|
|
border-radius: 0 !important; |
|
|
margin: 8px 0 !important; |
|
|
} |
|
|
|
|
|
/* Code blocks in chat */ |
|
|
code, pre { |
|
|
background: #000 !important; |
|
|
border: 2px solid #004488 !important; |
|
|
border-radius: 0 !important; |
|
|
color: #00ffff !important; |
|
|
font-family: 'JetBrains Mono', monospace !important; |
|
|
} |
|
|
|
|
|
/* Scrollbar */ |
|
|
::-webkit-scrollbar { |
|
|
width: 12px; |
|
|
height: 12px; |
|
|
} |
|
|
|
|
|
::-webkit-scrollbar-track { |
|
|
background: #0a0a0a; |
|
|
border: 2px solid #004488; |
|
|
} |
|
|
|
|
|
::-webkit-scrollbar-thumb { |
|
|
background: #0066ff; |
|
|
border: 2px solid #00aaff; |
|
|
} |
|
|
|
|
|
::-webkit-scrollbar-thumb:hover { |
|
|
background: #00aaff; |
|
|
} |
|
|
|
|
|
/* Status indicator */ |
|
|
.status-badge { |
|
|
display: inline-block; |
|
|
padding: 4px 16px; |
|
|
background: #0a0a0a; |
|
|
border: 2px solid #00ff00; |
|
|
font-family: 'VT323', monospace; |
|
|
font-size: 1.2rem; |
|
|
color: #00ff00; |
|
|
text-transform: uppercase; |
|
|
letter-spacing: 2px; |
|
|
animation: blink 1s infinite; |
|
|
} |
|
|
|
|
|
@keyframes blink { |
|
|
0%, 100% { opacity: 1; } |
|
|
50% { opacity: 0.5; } |
|
|
} |
|
|
|
|
|
/* Login button styling */ |
|
|
.login-btn { |
|
|
background: #001a33 !important; |
|
|
border: 3px solid #00aaff !important; |
|
|
} |
|
|
|
|
|
/* Panel styling */ |
|
|
.panel { |
|
|
background: #0d1a26 !important; |
|
|
border: 4px solid #004488 !important; |
|
|
border-radius: 0 !important; |
|
|
padding: 20px !important; |
|
|
} |
|
|
|
|
|
/* Terminal box styling */ |
|
|
.terminal-box { |
|
|
background: #0a0a0a; |
|
|
border: 3px solid #004488; |
|
|
padding: 1rem; |
|
|
margin-top: 1.5rem; |
|
|
font-family: 'JetBrains Mono', monospace; |
|
|
} |
|
|
|
|
|
.terminal-box h4 { |
|
|
color: #00ffff; |
|
|
margin: 0 0 0.5rem 0; |
|
|
font-family: 'VT323', monospace; |
|
|
font-size: 1.3rem; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
|
|
|
.terminal-box ul { |
|
|
color: #00aaff; |
|
|
font-size: 0.85rem; |
|
|
margin: 0; |
|
|
padding-left: 1.2rem; |
|
|
} |
|
|
|
|
|
.terminal-box li { |
|
|
margin: 4px 0; |
|
|
} |
|
|
|
|
|
.terminal-box li::marker { |
|
|
content: "> "; |
|
|
color: #0066ff; |
|
|
} |
|
|
|
|
|
/* Section headers */ |
|
|
.section-header { |
|
|
color: #00ffff; |
|
|
font-family: 'VT323', monospace; |
|
|
font-size: 1.5rem; |
|
|
letter-spacing: 2px; |
|
|
border-bottom: 2px solid #0066ff; |
|
|
padding-bottom: 0.5rem; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
|
|
|
/* Horizontal rule */ |
|
|
hr { |
|
|
border: none; |
|
|
border-top: 2px dashed #004488; |
|
|
margin: 1rem 0; |
|
|
} |
|
|
""" |
|
|
|
|
|
ASCII_HEADER = """ |
|
|
<div class="ascii-header"> |
|
|
<pre> |
|
|
██████╗ ██╗ ██╗███████╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ |
|
|
██╔═══██╗██║ ██║██╔════╝████╗ ██║ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗ |
|
|
██║ ██║██║ █╗ ██║█████╗ ██╔██╗ ██║ ██║ ██║ ██║██║ ██║█████╗ ██████╔╝ |
|
|
██║▄▄ ██║██║███╗██║██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗ |
|
|
╚██████╔╝╚███╔███╔╝███████╗██║ ╚████║ ╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║ |
|
|
╚══▀▀═╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ |
|
|
</pre> |
|
|
</div> |
|
|
""" |
|
|
|
|
|
SYSTEM_PROMPT = """You are QWEN CODER - an elite software engineering AI assistant powered by the Qwen3-Coder-Next model. You are a master-level full-stack developer with deep expertise across the entire technology stack. |
|
|
|
|
|
## Core Competencies |
|
|
- **Languages**: Python, JavaScript/TypeScript, Rust, Go, C/C++, Java, Kotlin, Swift, Ruby, PHP, SQL, and more |
|
|
- **Frontend**: React, Vue, Angular, Svelte, Next.js, Tailwind CSS, WebGL, Three.js |
|
|
- **Backend**: Node.js, FastAPI, Django, Flask, Spring Boot, Express, GraphQL, REST APIs |
|
|
- **Databases**: PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch, DynamoDB |
|
|
- **DevOps**: Docker, Kubernetes, CI/CD, AWS, GCP, Azure, Terraform, GitHub Actions |
|
|
- **AI/ML**: PyTorch, TensorFlow, Transformers, LangChain, vector databases, RAG systems |
|
|
|
|
|
## Your Approach |
|
|
1. **Analyze First**: Understand the problem deeply before coding |
|
|
2. **Clean Architecture**: Write modular, maintainable, well-documented code |
|
|
3. **Best Practices**: Follow SOLID principles, design patterns, and industry standards |
|
|
4. **Security Minded**: Always consider security implications and best practices |
|
|
5. **Performance Aware**: Optimize for efficiency without sacrificing readability |
|
|
6. **Test Driven**: Suggest tests and validation strategies |
|
|
|
|
|
## Response Style |
|
|
- Provide complete, production-ready code solutions |
|
|
- Explain complex concepts clearly with examples |
|
|
- Offer multiple approaches when appropriate |
|
|
- Include error handling and edge cases |
|
|
- Add helpful comments for complex logic |
|
|
- Suggest improvements and optimizations proactively |
|
|
|
|
|
You are direct, technical, and thorough. You don't just answer questions - you solve problems comprehensively.""" |
|
|
|
|
|
|
|
|
def respond( |
|
|
message, |
|
|
history: list[dict[str, str]], |
|
|
system_message, |
|
|
max_tokens, |
|
|
temperature, |
|
|
top_p, |
|
|
hf_token: gr.OAuthToken | None = None, |
|
|
): |
|
|
"""Stream responses from the Qwen Coder model.""" |
|
|
if hf_token is None: |
|
|
yield ">>> ERROR: Authentication required.\n>>> Please log in with your Hugging Face account to access this terminal." |
|
|
return |
|
|
|
|
|
client = InferenceClient(token=hf_token.token, model="Qwen/Qwen3-Coder-Next") |
|
|
|
|
|
messages = [{"role": "system", "content": system_message}] |
|
|
messages.extend(history) |
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
response = "" |
|
|
|
|
|
try: |
|
|
for chunk in client.chat_completion( |
|
|
messages, |
|
|
max_tokens=max_tokens, |
|
|
stream=True, |
|
|
temperature=temperature, |
|
|
top_p=top_p, |
|
|
): |
|
|
choices = chunk.choices |
|
|
if len(choices) and choices[0].delta.content: |
|
|
token = choices[0].delta.content |
|
|
response += token |
|
|
yield response |
|
|
except Exception as e: |
|
|
yield f">>> ERROR: {str(e)}\n>>> Connection failed. Retry recommended." |
|
|
|
|
|
|
|
|
|
|
|
with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Base(), title="QWEN CODER") as demo: |
|
|
|
|
|
|
|
|
gr.HTML(ASCII_HEADER) |
|
|
|
|
|
gr.HTML(""" |
|
|
<div class="subheader"> |
|
|
<span class="status-badge">● ONLINE</span> |
|
|
| POWERED BY QWEN3-CODER-NEXT |
|
|
</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
|
|
|
with gr.Column(scale=1, min_width=280): |
|
|
gr.HTML("<div class='section-header'>[ CONTROLS ]</div>") |
|
|
|
|
|
login_btn = gr.LoginButton(size="lg") |
|
|
|
|
|
gr.HTML("<hr>") |
|
|
|
|
|
with gr.Accordion("[ SYSTEM CONFIG ]", open=False): |
|
|
system_message = gr.Textbox( |
|
|
value=SYSTEM_PROMPT, |
|
|
label="System Prompt", |
|
|
lines=8, |
|
|
max_lines=20, |
|
|
) |
|
|
|
|
|
with gr.Accordion("[ GENERATION PARAMS ]", open=True): |
|
|
max_tokens = gr.Slider( |
|
|
minimum=256, |
|
|
maximum=8192, |
|
|
value=4096, |
|
|
step=256, |
|
|
label="Max Tokens", |
|
|
info="Maximum response length" |
|
|
) |
|
|
temperature = gr.Slider( |
|
|
minimum=0.0, |
|
|
maximum=2.0, |
|
|
value=0.7, |
|
|
step=0.05, |
|
|
label="Temperature", |
|
|
info="Higher = more creative" |
|
|
) |
|
|
top_p = gr.Slider( |
|
|
minimum=0.1, |
|
|
maximum=1.0, |
|
|
value=0.95, |
|
|
step=0.05, |
|
|
label="Top-P", |
|
|
info="Nucleus sampling" |
|
|
) |
|
|
|
|
|
gr.HTML(""" |
|
|
<div class="terminal-box"> |
|
|
<h4>[ QUICK TIPS ]</h4> |
|
|
<ul> |
|
|
<li>Be specific about requirements</li> |
|
|
<li>Mention languages/frameworks</li> |
|
|
<li>Ask for explanations</li> |
|
|
<li>Request code reviews</li> |
|
|
</ul> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
|
|
|
with gr.Column(scale=3): |
|
|
chatbot = gr.ChatInterface( |
|
|
respond, |
|
|
type="messages", |
|
|
additional_inputs=[ |
|
|
system_message, |
|
|
max_tokens, |
|
|
temperature, |
|
|
top_p, |
|
|
], |
|
|
examples=[ |
|
|
["Write a Python async web scraper with rate limiting and retry logic"], |
|
|
["Create a React component for an infinite scroll list with virtualization"], |
|
|
["Design a PostgreSQL schema for a multi-tenant SaaS application"], |
|
|
["Implement a Redis-based distributed lock in Python"], |
|
|
["Write a GitHub Actions workflow for CI/CD with Docker"], |
|
|
], |
|
|
cache_examples=False, |
|
|
chatbot=gr.Chatbot( |
|
|
height=600, |
|
|
show_label=False, |
|
|
container=True, |
|
|
show_copy_button=True, |
|
|
layout="panel", |
|
|
type="messages", |
|
|
), |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|