AIencoder commited on
Commit
8b257cb
·
verified ·
1 Parent(s): 0b1db20

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +445 -415
app.py CHANGED
@@ -1,55 +1,77 @@
1
  import gradio as gr
2
- import requests
3
  import json
4
  import time
5
  import os
 
 
6
  from faster_whisper import WhisperModel
7
 
8
- OLLAMA_URL = "http://localhost:11434"
9
- MAX_RETRIES = 3
10
- TIMEOUT = 300
11
-
12
- # ===== PERFORMANCE SETTINGS =====
13
- OLLAMA_OPTIONS = {
14
- "num_ctx": 4096, # Context window (lower = faster, 4096 is good balance)
15
- "num_batch": 512, # Batch size for prompt processing
16
- "num_thread": 4, # CPU threads (adjust based on your CPU)
17
- "repeat_penalty": 1.1, # Prevent repetition
18
- "top_k": 40, # Top-K sampling (lower = faster)
19
- "top_p": 0.9, # Nucleus sampling
20
- }
21
-
22
- # Keep model loaded for 10 minutes (faster subsequent requests)
23
- KEEP_ALIVE = "10m"
24
 
25
  MODELS = {
26
- "⭐ Qwen2.5 Coder 7B (Best)": "qwen2.5-coder:7b",
27
- "🧠 DeepSeek Coder 6.7B (Logic)": "deepseek-coder:6.7b",
28
- "Qwen2.5 Coder 3B (Fast)": "qwen2.5-coder:3b",
29
- "Qwen2.5 Coder 1.5B (Fastest)": "qwen2.5-coder:1.5b",
30
- "DeepSeek Coder 1.3B (Fast)": "deepseek-coder:1.3b",
31
- "StarCoder2 3B": "starcoder2:3b",
32
- "CodeGemma 2B (Fast)": "codegemma:2b",
33
  }
34
 
35
  MODEL_INFO = {
36
- "⭐ Qwen2.5 Coder 7B (Best)": "🏆 Best overall • ~4.5GB • Recommended",
37
- "🧠 DeepSeek Coder 6.7B (Logic)": "🧠 Best for algorithms & logic ~3.8GB",
38
- "Qwen2.5 Coder 3B (Fast)": "⚖️ Balanced • ~2GB • Great all-rounder",
39
- "Qwen2.5 Coder 1.5B (Fastest)": "⚡ Fastest • ~1GB • Quick tasks",
40
- "DeepSeek Coder 1.3B (Fast)": "⚡ Fast • ~0.8GB • Quick logic",
41
- "StarCoder2 3B": "🐙 GitHub trained • ~1.7GB • Real patterns",
42
- "CodeGemma 2B (Fast)": "🔷 Google • ~1.6GB • Quick & efficient",
43
  }
44
 
45
  LANGUAGES = [
46
  "Python", "JavaScript", "TypeScript", "Go", "Rust",
47
  "Java", "C++", "C#", "C", "PHP", "Ruby", "Swift", "Kotlin",
48
- "Scala", "R", "MATLAB", "Julia", "Perl",
49
- "HTML/CSS", "SQL", "Bash", "PowerShell", "Lua"
50
  ]
51
 
52
- # ===== WHISPER INIT =====
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  whisper_model = None
54
 
55
  def init_whisper():
@@ -58,139 +80,64 @@ def init_whisper():
58
  print("Loading Whisper...")
59
  whisper_model = WhisperModel("tiny", device="cpu", compute_type="int8")
60
  print("✅ Whisper ready!")
61
- return True
62
  except Exception as e:
63
- print(f"❌ Whisper failed to load: {e}")
64
- return False
65
 
66
  init_whisper()
67
 
68
- # ===== PRELOAD DEFAULT MODEL =====
69
- def preload_model():
70
- """Preload default model for faster first request"""
71
- try:
72
- print("🔥 Preloading default model...")
73
- requests.post(
74
- f"{OLLAMA_URL}/api/generate",
75
- json={
76
- "model": "qwen2.5-coder:3b",
77
- "prompt": "Hi",
78
- "keep_alive": KEEP_ALIVE,
79
- "options": {"num_predict": 1}
80
- },
81
- timeout=60
82
- )
83
- print("✅ Model preloaded!")
84
- except Exception as e:
85
- print(f"⚠️ Preload failed: {e}")
86
-
87
- # ===== HELPER FUNCTIONS =====
88
-
89
- def check_ollama_health():
90
- try:
91
- r = requests.get(f"{OLLAMA_URL}/api/tags", timeout=5)
92
- return r.status_code == 200
93
- except:
94
- return False
95
 
96
  def get_status():
97
- try:
98
- r = requests.get(f"{OLLAMA_URL}/api/tags", timeout=5)
99
- if r.status_code == 200:
100
- models = r.json().get("models", [])
101
- return f"🟢 Online • {len(models)} models"
102
- except requests.exceptions.ConnectionError:
103
- return "🔴 Offline • Ollama not running"
104
- except requests.exceptions.Timeout:
105
- return "🟡 Slow • Connection timeout"
106
- except Exception as e:
107
- return f"🔴 Error • {str(e)[:30]}"
108
- return "🟡 Starting..."
109
 
110
  def get_model_info(model_name):
111
  return MODEL_INFO.get(model_name, "")
112
 
113
- def validate_input(text, field_name="Input"):
114
  if not text or not text.strip():
115
- return False, f"⚠️ {field_name} cannot be empty."
116
- if len(text) > 100000:
117
- return False, f"⚠️ {field_name} is too long (max 100KB)."
118
  return True, None
119
 
120
  def transcribe_audio(audio):
121
- if audio is None:
122
  return ""
123
- if whisper_model is None:
124
- return "❌ Whisper not loaded. Voice input unavailable."
125
  try:
126
  segments, _ = whisper_model.transcribe(audio)
127
- text = " ".join([seg.text for seg in segments]).strip()
128
- if not text:
129
- return "⚠️ No speech detected. Try again."
130
- return text
131
- except FileNotFoundError:
132
- return "❌ Audio file not found."
133
  except Exception as e:
134
- return f"❌ Transcription failed: {str(e)[:50]}"
135
 
136
- def call_ollama_with_retry(model_name, prompt, temperature=0.7, max_tokens=2048):
137
- if not check_ollama_health():
138
- return "❌ **Ollama is not running.**\n\nPlease wait for Ollama to start."
 
139
 
140
- model = MODELS.get(model_name, "qwen2.5-coder:3b")
141
-
142
- # Merge performance options with request options
143
- options = {
144
- **OLLAMA_OPTIONS,
145
- "temperature": temperature,
146
- "num_predict": max_tokens
147
- }
148
-
149
- for attempt in range(MAX_RETRIES):
150
- try:
151
- r = requests.post(
152
- f"{OLLAMA_URL}/api/generate",
153
- json={
154
- "model": model,
155
- "prompt": prompt,
156
- "stream": False,
157
- "keep_alive": KEEP_ALIVE,
158
- "options": options
159
- },
160
- timeout=TIMEOUT
161
- )
162
-
163
- if r.status_code == 200:
164
- response = r.json().get("response", "")
165
- if not response.strip():
166
- return "⚠️ Model returned empty response. Try rephrasing."
167
- return response
168
- elif r.status_code == 404:
169
- return f"❌ **Model not found:** `{model}`"
170
- elif r.status_code == 500:
171
- error_msg = r.text[:200] if r.text else "Unknown error"
172
- if "out of memory" in error_msg.lower():
173
- return "❌ **Out of memory.** Try a smaller model."
174
- return f"❌ **Server error:** {error_msg}"
175
- else:
176
- return f"❌ **HTTP {r.status_code}:** {r.text[:100]}"
177
 
178
- except requests.exceptions.Timeout:
179
- if attempt < MAX_RETRIES - 1:
180
- time.sleep(2)
181
- continue
182
- return "❌ **Timeout.** Try smaller model or shorter input."
183
- except requests.exceptions.ConnectionError:
184
- if attempt < MAX_RETRIES - 1:
185
- time.sleep(2)
186
- continue
187
- return "❌ **Connection failed.** Ollama may have crashed."
188
- except json.JSONDecodeError:
189
- return "❌ **Invalid response from Ollama.**"
190
- except Exception as e:
191
- return f"❌ **Error:** {str(e)[:100]}"
192
-
193
- return "❌ **Max retries reached.**"
194
 
195
  def extract_code(text):
196
  if not text or "```" not in text:
@@ -206,7 +153,7 @@ def extract_code(text):
206
  pass
207
  return text
208
 
209
- # ===== STREAMING FUNCTIONS (FASTER FEEDBACK) =====
210
 
211
  def chat_stream(message, history, model_name, temperature, max_tokens):
212
  valid, error = validate_input(message, "Message")
@@ -214,273 +161,252 @@ def chat_stream(message, history, model_name, temperature, max_tokens):
214
  yield history + [[message, error]]
215
  return
216
 
217
- if not check_ollama_health():
218
- yield history + [[message, "❌ **Ollama not running.**"]]
 
219
  return
220
 
221
- model = MODELS.get(model_name, "qwen2.5-coder:3b")
222
- messages = [{"role": "system", "content": "Expert coding assistant. Use markdown code blocks."}]
223
-
224
- for user_msg, assistant_msg in history:
225
- messages.append({"role": "user", "content": user_msg})
226
- if assistant_msg:
227
- messages.append({"role": "assistant", "content": assistant_msg})
228
-
229
- messages.append({"role": "user", "content": message})
230
 
231
- options = {
232
- **OLLAMA_OPTIONS,
233
- "temperature": temperature,
234
- "num_predict": max_tokens
235
- }
236
-
237
  try:
238
- response = requests.post(
239
- f"{OLLAMA_URL}/api/chat",
240
- json={
241
- "model": model,
242
- "messages": messages,
243
- "stream": True,
244
- "keep_alive": KEEP_ALIVE,
245
- "options": options
246
- },
247
- stream=True,
248
- timeout=TIMEOUT
249
- )
250
-
251
- if response.status_code == 404:
252
- yield history + [[message, f"❌ **Model not found:** `{model}`"]]
253
- return
254
-
255
- if response.status_code != 200:
256
- yield history + [[message, f"❌ **Error {response.status_code}**"]]
257
- return
258
-
259
  full = ""
260
- for line in response.iter_lines():
261
- if line:
262
- try:
263
- data = json.loads(line)
264
- if "error" in data:
265
- yield history + [[message, f"❌ **Error:** {data['error']}"]]
266
- return
267
- if "message" in data:
268
- full += data["message"].get("content", "")
269
- yield history + [[message, full]]
270
- except json.JSONDecodeError:
271
- continue
272
-
273
- if not full.strip():
274
- yield history + [[message, "⚠️ Empty response. Try rephrasing."]]
275
-
276
- except requests.exceptions.Timeout:
277
- yield history + [[message, "❌ **Timeout.** Try smaller model."]]
278
- except requests.exceptions.ConnectionError:
279
- yield history + [[message, "❌ **Connection lost.**"]]
280
  except Exception as e:
281
- yield history + [[message, f"❌ **Error:** {str(e)[:50]}"]]
282
-
283
- # ===== STREAMING CODE GENERATION (NEW!) =====
284
 
285
- def generate_code_stream(prompt, language, model_name, temperature, max_tokens):
286
  valid, error = validate_input(prompt, "Description")
287
  if not valid:
288
  yield error
289
  return
290
 
291
- if not check_ollama_health():
292
- yield "❌ **Ollama not running.**"
 
293
  return
294
 
295
- model = MODELS.get(model_name, "qwen2.5-coder:3b")
296
 
297
- # Shorter, optimized prompt
298
- full_prompt = f"Write clean {language} code with comments for:\n{prompt}\n\nCode only:"
299
-
300
- options = {
301
- **OLLAMA_OPTIONS,
302
- "temperature": temperature,
303
- "num_predict": max_tokens
304
- }
305
-
306
  try:
307
- response = requests.post(
308
- f"{OLLAMA_URL}/api/generate",
309
- json={
310
- "model": model,
311
- "prompt": full_prompt,
312
- "stream": True,
313
- "keep_alive": KEEP_ALIVE,
314
- "options": options
315
- },
316
- stream=True,
317
- timeout=TIMEOUT
318
- )
319
-
320
- if response.status_code != 200:
321
- yield f"❌ **Error {response.status_code}**"
322
- return
323
-
324
  full = ""
325
- for line in response.iter_lines():
326
- if line:
327
- try:
328
- data = json.loads(line)
329
- if "response" in data:
330
- full += data["response"]
331
- # Extract code as we stream
332
- yield extract_code(full)
333
- except:
334
- continue
335
-
336
- except requests.exceptions.Timeout:
337
- yield "❌ **Timeout.**"
338
  except Exception as e:
339
- yield f"❌ **Error:** {str(e)[:50]}"
340
 
341
- # ===== OPTIMIZED CORE FUNCTIONS (SHORTER PROMPTS) =====
342
 
343
- def explain_code(code, model_name, detail_level, max_tokens):
344
- valid, error = validate_input(code, "Code")
345
  if not valid:
346
- return error
347
-
348
  prompts = {
349
  "Brief": f"Explain briefly (2-3 sentences):\n{code}",
350
  "Normal": f"Explain this code:\n{code}",
351
  "Detailed": f"Detailed explanation (purpose, logic, complexity, improvements):\n{code}"
352
  }
353
-
354
- return call_ollama_with_retry(model_name, prompts.get(detail_level, prompts["Normal"]), 0.5, max_tokens)
355
 
356
  def fix_code(code, error_msg, model_name, max_tokens):
357
- valid, error = validate_input(code, "Code")
358
  if not valid:
359
- return error
360
-
361
- err = error_msg.strip() if error_msg else "Not working"
362
- prompt = f"Fix this code. Error: {err}\n\n{code}\n\nFixed code and explanation:"
363
- return call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
364
 
365
  def review_code(code, model_name, max_tokens):
366
- valid, error = validate_input(code, "Code")
367
  if not valid:
368
- return error
369
-
370
- prompt = f"Review for bugs, performance, security, and improvements:\n{code}"
371
- return call_ollama_with_retry(model_name, prompt, 0.4, max_tokens)
372
 
373
- def convert_code(code, source_lang, target_lang, model_name, max_tokens):
374
- valid, error = validate_input(code, "Code")
375
  if not valid:
376
- return error
377
- if source_lang == target_lang:
378
- return "⚠️ Same language selected."
379
-
380
- prompt = f"Convert {source_lang} to {target_lang}. Output only code:\n{code}"
381
- result = call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
382
- return result if result.startswith("❌") or result.startswith("⚠️") else extract_code(result)
383
 
384
  def generate_tests(code, language, framework, model_name, max_tokens):
385
- valid, error = validate_input(code, "Code")
386
  if not valid:
387
- return error
388
-
389
- fw = framework.strip() if framework else "pytest" if language == "Python" else "Jest"
390
- prompt = f"Generate {fw} tests for this {language} code. Output only test code:\n{code}"
391
- result = call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
392
- return result if result.startswith("❌") or result.startswith("⚠️") else extract_code(result)
393
 
394
  def document_code(code, language, style, model_name, max_tokens):
395
- valid, error = validate_input(code, "Code")
396
  if not valid:
397
- return error
398
-
399
- prompt = f"Add {style.lower()} to this {language} code:\n{code}"
400
- result = call_ollama_with_retry(model_name, prompt, 0.4, max_tokens)
401
  return result if style == "README" or result.startswith("❌") else extract_code(result)
402
 
403
  def optimize_code(code, language, focus, model_name, max_tokens):
404
- valid, error = validate_input(code, "Code")
405
  if not valid:
406
- return error
407
-
408
- prompt = f"Optimize for {focus.lower()}. Explain changes:\n{code}"
409
- return call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
  def build_regex(description, model_name, max_tokens):
412
- valid, error = validate_input(description, "Description")
413
  if not valid:
414
- return error
415
-
416
- prompt = f"Create regex for: {description}\n\nPattern, explanation, examples, Python code:"
417
- return call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
418
 
419
  def build_api(description, framework, model_name, max_tokens):
420
- valid, error = validate_input(description, "Description")
421
  if not valid:
422
- return error
423
-
424
- prompt = f"Create {framework} REST endpoint:\n{description}\n\nCode with validation and error handling:"
425
- result = call_ollama_with_retry(model_name, prompt, 0.3, max_tokens)
426
  return result if result.startswith("❌") else extract_code(result)
427
 
428
- # ===== CSS =====
429
-
430
- css = """
431
- :root {
432
- --primary: #6366f1;
433
- --secondary: #8b5cf6;
434
- --bg-dark: #0f172a;
435
- --bg-card: #1e293b;
436
- --border: #334155;
437
- --text-primary: #f1f5f9;
438
- --gradient: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #06b6d4 100%);
439
- }
440
- .gradio-container { max-width: 1500px !important; margin: auto !important; }
441
- .header-section {
442
- background: var(--gradient);
443
- border-radius: 20px;
444
- padding: 32px 40px;
445
- margin-bottom: 24px;
446
- box-shadow: 0 20px 40px rgba(99, 102, 241, 0.3);
447
- }
448
- .header-title { color: white; margin: 0; font-size: 2.5rem; font-weight: 800; }
449
- .header-subtitle { color: rgba(255,255,255,0.9); margin: 8px 0 0 0; }
450
- .header-badges { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
451
- .badge {
452
- background: rgba(255,255,255,0.2);
453
- padding: 8px 16px;
454
- border-radius: 50px;
455
- font-size: 0.85rem;
456
- color: white;
457
- }
458
- .tab-nav button.selected {
459
- background: var(--gradient) !important;
460
- color: white !important;
461
- }
462
- button.primary {
463
- background: var(--gradient) !important;
464
- border: none !important;
465
- border-radius: 10px !important;
466
- }
467
- .footer { text-align: center; padding: 24px; color: #94a3b8; font-size: 0.85rem; }
468
- footer { display: none !important; }
469
- """
470
 
471
  # ===== UI =====
472
 
473
  with gr.Blocks(title="Axon v6") as demo:
474
 
475
  gr.HTML("""
476
- <div class="header-section">
477
- <h1 class="header-title">🔥 Axon v6</h1>
478
- <p class="header-subtitle">AI-Powered Coding AssistantOptimized for Speed</p>
479
- <div class="header-badges">
480
- <span class="badge">🤖 7 Models</span>
481
- <span class="badge">🛠️ 9 Tools</span>
482
- <span class="badge">⚡ Optimized</span>
483
- <span class="badge">🔒 100% Local</span>
484
  </div>
485
  </div>
486
  """)
@@ -490,127 +416,219 @@ with gr.Blocks(title="Axon v6") as demo:
490
  with gr.Row():
491
  model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
492
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
493
- max_tokens = gr.Slider(256, 8192, value=2048, step=256, label="📏 Max Tokens", scale=2)
494
 
495
- model_info = gr.Markdown(value="⚖️ Balanced • ~2GB • Great all-rounder")
496
  model_dropdown.change(get_model_info, model_dropdown, model_info)
497
 
498
  with gr.Tabs():
499
 
500
  with gr.TabItem("💬 Chat"):
501
- chatbot = gr.Chatbot(height=500)
502
  with gr.Row():
503
  msg = gr.Textbox(placeholder="Ask anything...", show_label=False, scale=8)
504
- send = gr.Button("Send", variant="primary", scale=1)
505
  with gr.Row():
506
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
507
  transcribe = gr.Button("🎤 Transcribe", scale=1)
508
  clear = gr.Button("🗑️ Clear", scale=1)
509
- with gr.Accordion("💡 Examples", open=False):
510
- gr.Examples(["Write a Python quicksort", "Explain async/await in JS"], inputs=msg)
511
 
512
  with gr.TabItem("⚡ Generate"):
513
  with gr.Row():
514
- with gr.Column(scale=1):
515
- gen_prompt = gr.Textbox(label="📝 Describe what to build", lines=4)
516
  with gr.Row():
517
- gen_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language", scale=2)
518
- gen_temp = gr.Slider(0, 1, value=0.3, step=0.1, label="🌡️", scale=1)
519
- gen_btn = gr.Button("⚡ Generate (Streaming)", variant="primary")
520
- with gr.Column(scale=2):
521
- gen_output = gr.Code(label="Code", language="python", lines=18)
522
 
523
  with gr.TabItem("🔍 Explain"):
524
  with gr.Row():
525
- with gr.Column(scale=1):
526
- explain_input = gr.Code(label="📋 Code", lines=12)
527
- explain_detail = gr.Radio(["Brief", "Normal", "Detailed"], value="Normal", label="Detail")
528
  explain_btn = gr.Button("🔍 Explain", variant="primary")
529
- with gr.Column(scale=1):
530
  explain_output = gr.Markdown()
531
 
532
  with gr.TabItem("🔧 Debug"):
533
  with gr.Row():
534
- with gr.Column(scale=1):
535
- fix_input = gr.Code(label="🐛 Code", lines=10)
536
- fix_error = gr.Textbox(label="Error", lines=2)
537
  fix_btn = gr.Button("🔧 Fix", variant="primary")
538
- with gr.Column(scale=1):
539
  fix_output = gr.Markdown()
540
 
541
  with gr.TabItem("📋 Review"):
542
  with gr.Row():
543
- with gr.Column(scale=1):
544
- review_input = gr.Code(label="📋 Code", lines=14)
545
  review_btn = gr.Button("📋 Review", variant="primary")
546
- with gr.Column(scale=1):
547
  review_output = gr.Markdown()
548
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  with gr.TabItem("🔄 Convert"):
550
  with gr.Row():
551
- with gr.Column(scale=1):
552
- convert_input = gr.Code(label="📥 Source", lines=12)
553
  with gr.Row():
554
  convert_from = gr.Dropdown(LANGUAGES, value="Python", label="From")
555
  convert_to = gr.Dropdown(LANGUAGES, value="JavaScript", label="To")
556
  convert_btn = gr.Button("🔄 Convert", variant="primary")
557
- with gr.Column(scale=1):
558
- convert_output = gr.Code(label="📤 Result", lines=12)
559
 
560
  with gr.TabItem("🧪 Test"):
561
  with gr.Row():
562
- with gr.Column(scale=1):
563
- test_input = gr.Code(label="📋 Code", lines=12)
564
  with gr.Row():
565
- test_lang = gr.Dropdown(LANGUAGES[:12], value="Python", label="Language")
566
  test_fw = gr.Textbox(label="Framework", placeholder="pytest")
567
- test_btn = gr.Button("🧪 Generate Tests", variant="primary")
568
- with gr.Column(scale=1):
569
- test_output = gr.Code(label="Tests", lines=12)
570
 
571
  with gr.TabItem("📝 Document"):
572
  with gr.Row():
573
- with gr.Column(scale=1):
574
- doc_input = gr.Code(label="📋 Code", lines=12)
575
  with gr.Row():
576
  doc_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
577
- doc_style = gr.Dropdown(["Docstrings", "Comments", "Both", "README"], value="Both", label="Style")
578
  doc_btn = gr.Button("📝 Document", variant="primary")
579
- with gr.Column(scale=1):
580
- doc_output = gr.Code(label="Documented", lines=12)
581
 
582
  with gr.TabItem("🚀 Optimize"):
583
  with gr.Row():
584
- with gr.Column(scale=1):
585
- opt_input = gr.Code(label="📋 Code", lines=12)
586
  with gr.Row():
587
  opt_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
588
- opt_focus = gr.Dropdown(["All", "Performance", "Readability", "Memory"], value="All", label="Focus")
589
  opt_btn = gr.Button("🚀 Optimize", variant="primary")
590
- with gr.Column(scale=1):
591
  opt_output = gr.Markdown()
592
 
593
- with gr.TabItem("🛠️ Tools"):
594
- gr.Markdown("### 🎯 Regex Builder")
595
  with gr.Row():
596
  with gr.Column():
597
- regex_desc = gr.Textbox(label="Describe pattern", lines=2)
598
- regex_btn = gr.Button("🎯 Build Regex", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  with gr.Column():
600
  regex_output = gr.Markdown()
601
 
602
- gr.Markdown("---\n### 🔗 API Builder")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
  with gr.Row():
604
  with gr.Column():
605
- api_desc = gr.Textbox(label="Describe endpoint", lines=2)
606
- api_fw = gr.Dropdown(["FastAPI", "Express", "Flask", "Gin"], value="FastAPI", label="Framework")
607
- api_btn = gr.Button("🔗 Build API", variant="primary")
 
 
608
  with gr.Column():
609
- api_output = gr.Code(label="API Code", lines=12)
610
 
611
- gr.HTML('<div class="footer">🔒 100% Local Optimized for Speed • Built with ❤️</div>')
612
 
613
- # Events
614
  def respond(message, history, model, temp, tokens):
615
  history = history or []
616
  for updated in chat_stream(message, history, model, temp, tokens):
@@ -621,9 +639,7 @@ with gr.Blocks(title="Axon v6") as demo:
621
  clear.click(lambda: [], None, chatbot)
622
  transcribe.click(transcribe_audio, audio, msg)
623
 
624
- # Streaming generate!
625
- gen_btn.click(generate_code_stream, [gen_prompt, gen_lang, model_dropdown, gen_temp, max_tokens], gen_output)
626
-
627
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
628
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
629
  review_btn.click(review_code, [review_input, model_dropdown, max_tokens], review_output)
@@ -631,10 +647,24 @@ with gr.Blocks(title="Axon v6") as demo:
631
  test_btn.click(generate_tests, [test_input, test_lang, test_fw, model_dropdown, max_tokens], test_output)
632
  doc_btn.click(document_code, [doc_input, doc_lang, doc_style, model_dropdown, max_tokens], doc_output)
633
  opt_btn.click(optimize_code, [opt_input, opt_lang, opt_focus, model_dropdown, max_tokens], opt_output)
 
 
 
 
 
 
 
 
 
 
634
  regex_btn.click(build_regex, [regex_desc, model_dropdown, max_tokens], regex_output)
635
  api_btn.click(build_api, [api_desc, api_fw, model_dropdown, max_tokens], api_output)
 
 
 
636
 
637
- # Preload model on startup
638
- preload_model()
 
639
 
640
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import gradio as gr
 
2
  import json
3
  import time
4
  import os
5
+ from pathlib import Path
6
+ from llama_cpp import Llama
7
  from faster_whisper import WhisperModel
8
 
9
+ # ===== CONFIG =====
10
+ MODELS_DIR = "/models"
11
+ MAX_TOKENS = 2048
12
+ CONTEXT_SIZE = 4096
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  MODELS = {
15
+ "⭐ Qwen2.5 Coder 7B (Best)": "qwen2.5-coder-7b-instruct-q4_k_m.gguf",
16
+ "Qwen2.5 Coder 3B (Fast)": "qwen2.5-coder-3b-instruct-q4_k_m.gguf",
17
+ "Qwen2.5 Coder 1.5B (Fastest)": "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",
 
 
 
 
18
  }
19
 
20
  MODEL_INFO = {
21
+ "⭐ Qwen2.5 Coder 7B (Best)": "🏆 Best quality • ~4.5GB",
22
+ "Qwen2.5 Coder 3B (Fast)": "⚖️ Balanced ~2GBRecommended",
23
+ "Qwen2.5 Coder 1.5B (Fastest)": " Fastest • ~1GB",
 
 
 
 
24
  }
25
 
26
  LANGUAGES = [
27
  "Python", "JavaScript", "TypeScript", "Go", "Rust",
28
  "Java", "C++", "C#", "C", "PHP", "Ruby", "Swift", "Kotlin",
29
+ "Scala", "R", "Julia", "Perl", "HTML/CSS", "SQL", "Bash", "PowerShell", "Lua"
 
30
  ]
31
 
32
+ # ===== MODEL CACHE =====
33
+ loaded_models = {}
34
+ current_model_name = None
35
+
36
+ def load_model(model_name):
37
+ global loaded_models, current_model_name
38
+
39
+ if model_name == current_model_name and model_name in loaded_models:
40
+ return loaded_models[model_name]
41
+
42
+ # Unload previous model to save RAM
43
+ if current_model_name and current_model_name != model_name:
44
+ if current_model_name in loaded_models:
45
+ del loaded_models[current_model_name]
46
+ print(f"🗑️ Unloaded {current_model_name}")
47
+
48
+ filename = MODELS.get(model_name)
49
+ if not filename:
50
+ return None
51
+
52
+ model_path = os.path.join(MODELS_DIR, filename)
53
+ if not os.path.exists(model_path):
54
+ print(f"❌ Model not found: {model_path}")
55
+ return None
56
+
57
+ print(f"📥 Loading {model_name}...")
58
+ try:
59
+ llm = Llama(
60
+ model_path=model_path,
61
+ n_ctx=CONTEXT_SIZE,
62
+ n_threads=4,
63
+ n_batch=512,
64
+ verbose=False
65
+ )
66
+ loaded_models[model_name] = llm
67
+ current_model_name = model_name
68
+ print(f"✅ {model_name} loaded!")
69
+ return llm
70
+ except Exception as e:
71
+ print(f"❌ Failed to load {model_name}: {e}")
72
+ return None
73
+
74
+ # ===== WHISPER =====
75
  whisper_model = None
76
 
77
  def init_whisper():
 
80
  print("Loading Whisper...")
81
  whisper_model = WhisperModel("tiny", device="cpu", compute_type="int8")
82
  print("✅ Whisper ready!")
 
83
  except Exception as e:
84
+ print(f"❌ Whisper failed: {e}")
 
85
 
86
  init_whisper()
87
 
88
+ # ===== HELPERS =====
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  def get_status():
91
+ available = [name for name, file in MODELS.items() if os.path.exists(os.path.join(MODELS_DIR, file))]
92
+ if current_model_name:
93
+ return f"🟢 Ready • {len(available)} models • Active: {current_model_name.split()[1] if len(current_model_name.split()) > 1 else current_model_name}"
94
+ return f"🟡 {len(available)} models available"
 
 
 
 
 
 
 
 
95
 
96
  def get_model_info(model_name):
97
  return MODEL_INFO.get(model_name, "")
98
 
99
+ def validate_input(text, name="Input"):
100
  if not text or not text.strip():
101
+ return False, f"⚠️ {name} cannot be empty."
102
+ if len(text) > 50000:
103
+ return False, f"⚠️ {name} too long."
104
  return True, None
105
 
106
  def transcribe_audio(audio):
107
+ if not audio:
108
  return ""
109
+ if not whisper_model:
110
+ return "❌ Whisper unavailable."
111
  try:
112
  segments, _ = whisper_model.transcribe(audio)
113
+ return " ".join([s.text for s in segments]).strip() or "⚠️ No speech detected."
 
 
 
 
 
114
  except Exception as e:
115
+ return f"❌ {str(e)[:50]}"
116
 
117
+ def generate_response(model_name, prompt, temperature=0.7, max_tokens=2048):
118
+ llm = load_model(model_name)
119
+ if not llm:
120
+ return "❌ **Model not available.** Check if downloaded."
121
 
122
+ try:
123
+ # Qwen2.5 chat format
124
+ formatted = f"<|im_start|>system\nYou are an expert coding assistant.<|im_end|>\n<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
+ output = llm(
127
+ formatted,
128
+ max_tokens=max_tokens,
129
+ temperature=temperature,
130
+ top_p=0.9,
131
+ top_k=40,
132
+ repeat_penalty=1.1,
133
+ stop=["<|im_end|>", "<|im_start|>"],
134
+ echo=False
135
+ )
136
+
137
+ response = output["choices"][0]["text"].strip()
138
+ return response if response else "⚠️ Empty response."
139
+ except Exception as e:
140
+ return f"❌ **Error:** {str(e)[:100]}"
 
141
 
142
  def extract_code(text):
143
  if not text or "```" not in text:
 
153
  pass
154
  return text
155
 
156
+ # ===== STREAMING =====
157
 
158
  def chat_stream(message, history, model_name, temperature, max_tokens):
159
  valid, error = validate_input(message, "Message")
 
161
  yield history + [[message, error]]
162
  return
163
 
164
+ llm = load_model(model_name)
165
+ if not llm:
166
+ yield history + [[message, "❌ Model not available."]]
167
  return
168
 
169
+ # Build conversation
170
+ conv = "<|im_start|>system\nYou are an expert coding assistant. Use markdown code blocks.<|im_end|>\n"
171
+ for u, a in history:
172
+ conv += f"<|im_start|>user\n{u}<|im_end|>\n"
173
+ if a:
174
+ conv += f"<|im_start|>assistant\n{a}<|im_end|>\n"
175
+ conv += f"<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
 
 
176
 
 
 
 
 
 
 
177
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  full = ""
179
+ for chunk in llm(
180
+ conv,
181
+ max_tokens=max_tokens,
182
+ temperature=temperature,
183
+ top_p=0.9,
184
+ stop=["<|im_end|>", "<|im_start|>"],
185
+ stream=True
186
+ ):
187
+ token = chunk["choices"][0]["text"]
188
+ full += token
189
+ yield history + [[message, full]]
 
 
 
 
 
 
 
 
 
190
  except Exception as e:
191
+ yield history + [[message, f"❌ {str(e)[:50]}"]]
 
 
192
 
193
+ def generate_stream(prompt, language, model_name, temperature, max_tokens):
194
  valid, error = validate_input(prompt, "Description")
195
  if not valid:
196
  yield error
197
  return
198
 
199
+ llm = load_model(model_name)
200
+ if not llm:
201
+ yield "❌ Model not available."
202
  return
203
 
204
+ formatted = f"<|im_start|>system\nYou are an expert coder.<|im_end|>\n<|im_start|>user\nWrite clean {language} code with comments:\n{prompt}\n\nOutput only code:<|im_end|>\n<|im_start|>assistant\n"
205
 
 
 
 
 
 
 
 
 
 
206
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  full = ""
208
+ for chunk in llm(formatted, max_tokens=max_tokens, temperature=temperature, stop=["<|im_end|>"], stream=True):
209
+ full += chunk["choices"][0]["text"]
210
+ yield extract_code(full)
 
 
 
 
 
 
 
 
 
 
211
  except Exception as e:
212
+ yield f"❌ {str(e)[:50]}"
213
 
214
+ # ===== CORE FEATURES =====
215
 
216
+ def explain_code(code, model_name, detail, max_tokens):
217
+ valid, err = validate_input(code, "Code")
218
  if not valid:
219
+ return err
 
220
  prompts = {
221
  "Brief": f"Explain briefly (2-3 sentences):\n{code}",
222
  "Normal": f"Explain this code:\n{code}",
223
  "Detailed": f"Detailed explanation (purpose, logic, complexity, improvements):\n{code}"
224
  }
225
+ return generate_response(model_name, prompts.get(detail, prompts["Normal"]), 0.5, max_tokens)
 
226
 
227
  def fix_code(code, error_msg, model_name, max_tokens):
228
+ valid, err = validate_input(code, "Code")
229
  if not valid:
230
+ return err
231
+ e = error_msg.strip() if error_msg else "Not working"
232
+ return generate_response(model_name, f"Fix this code. Error: {e}\n\n{code}\n\nFixed code and explanation:", 0.3, max_tokens)
 
 
233
 
234
  def review_code(code, model_name, max_tokens):
235
+ valid, err = validate_input(code, "Code")
236
  if not valid:
237
+ return err
238
+ return generate_response(model_name, f"Review for bugs, performance, security:\n{code}", 0.4, max_tokens)
 
 
239
 
240
+ def convert_code(code, from_lang, to_lang, model_name, max_tokens):
241
+ valid, err = validate_input(code, "Code")
242
  if not valid:
243
+ return err
244
+ if from_lang == to_lang:
245
+ return "⚠️ Same language."
246
+ result = generate_response(model_name, f"Convert {from_lang} to {to_lang}. Code only:\n{code}", 0.3, max_tokens)
247
+ return result if result.startswith("❌") else extract_code(result)
 
 
248
 
249
  def generate_tests(code, language, framework, model_name, max_tokens):
250
+ valid, err = validate_input(code, "Code")
251
  if not valid:
252
+ return err
253
+ fw = framework.strip() if framework else "pytest"
254
+ result = generate_response(model_name, f"Generate {fw} tests for {language}. Code only:\n{code}", 0.3, max_tokens)
255
+ return result if result.startswith("❌") else extract_code(result)
 
 
256
 
257
  def document_code(code, language, style, model_name, max_tokens):
258
+ valid, err = validate_input(code, "Code")
259
  if not valid:
260
+ return err
261
+ result = generate_response(model_name, f"Add {style.lower()} to this {language} code:\n{code}", 0.4, max_tokens)
 
 
262
  return result if style == "README" or result.startswith("❌") else extract_code(result)
263
 
264
  def optimize_code(code, language, focus, model_name, max_tokens):
265
+ valid, err = validate_input(code, "Code")
266
  if not valid:
267
+ return err
268
+ return generate_response(model_name, f"Optimize {language} for {focus.lower()}. Explain:\n{code}", 0.3, max_tokens)
269
+
270
+ # ===== NEW FEATURES =====
271
+
272
+ def security_scan(code, model_name, max_tokens):
273
+ valid, err = validate_input(code, "Code")
274
+ if not valid:
275
+ return err
276
+ prompt = """Security audit this code. Check for:
277
+ 1. Injection vulnerabilities (SQL, XSS, Command)
278
+ 2. Authentication issues
279
+ 3. Data exposure
280
+ 4. Input validation
281
+ 5. Cryptography issues
282
+
283
+ For each issue: Severity (🔴🟠🟡🟢), Location, Description, Fix.
284
+
285
+ Code:
286
+ """ + code
287
+ return generate_response(model_name, prompt, 0.3, max_tokens)
288
+
289
+ def analyze_complexity(code, model_name, max_tokens):
290
+ valid, err = validate_input(code, "Code")
291
+ if not valid:
292
+ return err
293
+ prompt = """Analyze time and space complexity:
294
+ 1. Time Complexity (Big O)
295
+ 2. Space Complexity (Big O)
296
+ 3. Best/Average/Worst cases
297
+ 4. Bottlenecks
298
+ 5. Optimization suggestions
299
+
300
+ Code:
301
+ """ + code
302
+ return generate_response(model_name, prompt, 0.4, max_tokens)
303
+
304
+ def build_sql(description, db_type, model_name, max_tokens):
305
+ valid, err = validate_input(description, "Description")
306
+ if not valid:
307
+ return err
308
+ result = generate_response(model_name, f"Write optimized {db_type} SQL for:\n{description}\n\nSQL only:", 0.2, max_tokens)
309
+ return result if result.startswith("❌") else extract_code(result)
310
+
311
+ def build_shell(description, shell_type, model_name, max_tokens):
312
+ valid, err = validate_input(description, "Description")
313
+ if not valid:
314
+ return err
315
+ result = generate_response(model_name, f"Write {shell_type} command for:\n{description}\n\nCommand only:", 0.2, max_tokens)
316
+ return result if result.startswith("❌") else extract_code(result)
317
+
318
+ def code_diff(code1, code2, model_name, max_tokens):
319
+ v1, e1 = validate_input(code1, "Code 1")
320
+ v2, e2 = validate_input(code2, "Code 2")
321
+ if not v1:
322
+ return e1
323
+ if not v2:
324
+ return e2
325
+ prompt = f"""Compare these code snippets:
326
+ 1. Key differences
327
+ 2. Functionality changes
328
+ 3. Performance impact
329
+ 4. Which is better and why
330
+
331
+ === CODE 1 ===
332
+ {code1}
333
+
334
+ === CODE 2 ===
335
+ {code2}"""
336
+ return generate_response(model_name, prompt, 0.4, max_tokens)
337
+
338
+ def generate_mock_data(schema, count, format_type, model_name, max_tokens):
339
+ valid, err = validate_input(schema, "Schema")
340
+ if not valid:
341
+ return err
342
+ result = generate_response(model_name, f"Generate {count} realistic mock entries as {format_type}:\n{schema}", 0.7, max_tokens)
343
+ return result if result.startswith("❌") else extract_code(result)
344
+
345
+ def interview_challenge(topic, difficulty, language, model_name, max_tokens):
346
+ valid, err = validate_input(topic, "Topic")
347
+ if not valid:
348
+ return err
349
+ prompt = f"""Create {difficulty} {language} interview challenge about {topic}.
350
+
351
+ Include:
352
+ 1. Problem statement
353
+ 2. Examples (2-3)
354
+ 3. Constraints
355
+ 4. Hints
356
+ 5. Solution with explanation"""
357
+ return generate_response(model_name, prompt, 0.6, max_tokens)
358
+
359
+ def to_pseudocode(code, output_type, model_name, max_tokens):
360
+ valid, err = validate_input(code, "Code")
361
+ if not valid:
362
+ return err
363
+ if output_type == "Pseudocode":
364
+ prompt = f"Convert to pseudocode:\n{code}"
365
+ else:
366
+ prompt = f"Create Mermaid.js flowchart for:\n{code}"
367
+ return generate_response(model_name, prompt, 0.3, max_tokens)
368
+
369
+ def build_cron(description, model_name, max_tokens):
370
+ valid, err = validate_input(description, "Description")
371
+ if not valid:
372
+ return err
373
+ return generate_response(model_name, f"Create cron expression for: {description}\n\nInclude: expression, breakdown, next 5 runs", 0.2, max_tokens)
374
 
375
  def build_regex(description, model_name, max_tokens):
376
+ valid, err = validate_input(description, "Description")
377
  if not valid:
378
+ return err
379
+ return generate_response(model_name, f"Create regex for: {description}\n\nPattern, explanation, examples, Python code:", 0.3, max_tokens)
 
 
380
 
381
  def build_api(description, framework, model_name, max_tokens):
382
+ valid, err = validate_input(description, "Description")
383
  if not valid:
384
+ return err
385
+ result = generate_response(model_name, f"Create {framework} REST endpoint:\n{description}\n\nCode:", 0.3, max_tokens)
 
 
386
  return result if result.startswith("❌") else extract_code(result)
387
 
388
+ def convert_data_format(data, from_fmt, to_fmt, model_name, max_tokens):
389
+ valid, err = validate_input(data, "Data")
390
+ if not valid:
391
+ return err
392
+ if from_fmt == to_fmt:
393
+ return "⚠️ Same format."
394
+ result = generate_response(model_name, f"Convert {from_fmt} to {to_fmt}:\n{data}\n\nOutput only:", 0.1, max_tokens)
395
+ return result if result.startswith("❌") else extract_code(result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
 
397
  # ===== UI =====
398
 
399
  with gr.Blocks(title="Axon v6") as demo:
400
 
401
  gr.HTML("""
402
+ <div style="background: linear-gradient(135deg, #6366f1, #8b5cf6, #06b6d4); border-radius: 16px; padding: 24px; margin-bottom: 16px;">
403
+ <h1 style="color: white; margin: 0; font-size: 2rem;">🔥 Axon v6</h1>
404
+ <p style="color: rgba(255,255,255,0.9); margin: 4px 0 0 0;">llama.cpp Edition 19 Tools Your Wheels! 🛞</p>
405
+ <div style="display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap;">
406
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🤖 3 Models</span>
407
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🛠️ 19 Tools</span>
408
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">⚡ llama.cpp</span>
409
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🔒 Local</span>
410
  </div>
411
  </div>
412
  """)
 
416
  with gr.Row():
417
  model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
418
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
419
+ max_tokens = gr.Slider(256, 4096, value=2048, step=256, label="📏 Max Tokens", scale=2)
420
 
421
+ model_info = gr.Markdown(value="⚖️ Balanced • ~2GB • Recommended")
422
  model_dropdown.change(get_model_info, model_dropdown, model_info)
423
 
424
  with gr.Tabs():
425
 
426
  with gr.TabItem("💬 Chat"):
427
+ chatbot = gr.Chatbot(height=400)
428
  with gr.Row():
429
  msg = gr.Textbox(placeholder="Ask anything...", show_label=False, scale=8)
430
+ send = gr.Button("Send", variant="primary", scale=1)
431
  with gr.Row():
432
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
433
  transcribe = gr.Button("🎤 Transcribe", scale=1)
434
  clear = gr.Button("🗑️ Clear", scale=1)
 
 
435
 
436
  with gr.TabItem("⚡ Generate"):
437
  with gr.Row():
438
+ with gr.Column():
439
+ gen_prompt = gr.Textbox(label="📝 Describe", lines=3)
440
  with gr.Row():
441
+ gen_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
442
+ gen_temp = gr.Slider(0, 1, value=0.3, step=0.1, label="🌡️")
443
+ gen_btn = gr.Button("⚡ Generate", variant="primary")
444
+ with gr.Column():
445
+ gen_output = gr.Code(label="Code", language="python", lines=14)
446
 
447
  with gr.TabItem("🔍 Explain"):
448
  with gr.Row():
449
+ with gr.Column():
450
+ explain_input = gr.Code(label="Code", lines=10)
451
+ explain_detail = gr.Radio(["Brief", "Normal", "Detailed"], value="Normal")
452
  explain_btn = gr.Button("🔍 Explain", variant="primary")
453
+ with gr.Column():
454
  explain_output = gr.Markdown()
455
 
456
  with gr.TabItem("🔧 Debug"):
457
  with gr.Row():
458
+ with gr.Column():
459
+ fix_input = gr.Code(label="Code", lines=8)
460
+ fix_error = gr.Textbox(label="Error", lines=2)
461
  fix_btn = gr.Button("🔧 Fix", variant="primary")
462
+ with gr.Column():
463
  fix_output = gr.Markdown()
464
 
465
  with gr.TabItem("📋 Review"):
466
  with gr.Row():
467
+ with gr.Column():
468
+ review_input = gr.Code(label="Code", lines=10)
469
  review_btn = gr.Button("📋 Review", variant="primary")
470
+ with gr.Column():
471
  review_output = gr.Markdown()
472
 
473
+ with gr.TabItem("🔐 Security"):
474
+ with gr.Row():
475
+ with gr.Column():
476
+ security_input = gr.Code(label="Code", lines=10)
477
+ security_btn = gr.Button("🔐 Scan", variant="primary")
478
+ with gr.Column():
479
+ security_output = gr.Markdown()
480
+
481
+ with gr.TabItem("📊 Complexity"):
482
+ with gr.Row():
483
+ with gr.Column():
484
+ complexity_input = gr.Code(label="Code", lines=10)
485
+ complexity_btn = gr.Button("📊 Analyze", variant="primary")
486
+ with gr.Column():
487
+ complexity_output = gr.Markdown()
488
+
489
  with gr.TabItem("🔄 Convert"):
490
  with gr.Row():
491
+ with gr.Column():
492
+ convert_input = gr.Code(label="Source", lines=10)
493
  with gr.Row():
494
  convert_from = gr.Dropdown(LANGUAGES, value="Python", label="From")
495
  convert_to = gr.Dropdown(LANGUAGES, value="JavaScript", label="To")
496
  convert_btn = gr.Button("🔄 Convert", variant="primary")
497
+ with gr.Column():
498
+ convert_output = gr.Code(label="Result", lines=10)
499
 
500
  with gr.TabItem("🧪 Test"):
501
  with gr.Row():
502
+ with gr.Column():
503
+ test_input = gr.Code(label="Code", lines=10)
504
  with gr.Row():
505
+ test_lang = gr.Dropdown(LANGUAGES[:10], value="Python", label="Language")
506
  test_fw = gr.Textbox(label="Framework", placeholder="pytest")
507
+ test_btn = gr.Button("🧪 Generate", variant="primary")
508
+ with gr.Column():
509
+ test_output = gr.Code(label="Tests", lines=10)
510
 
511
  with gr.TabItem("📝 Document"):
512
  with gr.Row():
513
+ with gr.Column():
514
+ doc_input = gr.Code(label="Code", lines=10)
515
  with gr.Row():
516
  doc_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
517
+ doc_style = gr.Dropdown(["Docstrings", "Comments", "Both", "README"], value="Both")
518
  doc_btn = gr.Button("📝 Document", variant="primary")
519
+ with gr.Column():
520
+ doc_output = gr.Code(label="Documented", lines=10)
521
 
522
  with gr.TabItem("🚀 Optimize"):
523
  with gr.Row():
524
+ with gr.Column():
525
+ opt_input = gr.Code(label="Code", lines=10)
526
  with gr.Row():
527
  opt_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
528
+ opt_focus = gr.Dropdown(["All", "Performance", "Readability", "Memory"], value="All")
529
  opt_btn = gr.Button("🚀 Optimize", variant="primary")
530
+ with gr.Column():
531
  opt_output = gr.Markdown()
532
 
533
+ with gr.TabItem("🔀 Diff"):
 
534
  with gr.Row():
535
  with gr.Column():
536
+ diff_code1 = gr.Code(label="Code 1", lines=8)
537
+ diff_code2 = gr.Code(label="Code 2", lines=8)
538
+ diff_btn = gr.Button("🔀 Compare", variant="primary")
539
+ with gr.Column():
540
+ diff_output = gr.Markdown()
541
+
542
+ with gr.TabItem("📐 Pseudo"):
543
+ with gr.Row():
544
+ with gr.Column():
545
+ pseudo_input = gr.Code(label="Code", lines=10)
546
+ pseudo_type = gr.Radio(["Pseudocode", "Flowchart"], value="Pseudocode")
547
+ pseudo_btn = gr.Button("📐 Convert", variant="primary")
548
+ with gr.Column():
549
+ pseudo_output = gr.Markdown()
550
+
551
+ with gr.TabItem("🎓 Interview"):
552
+ with gr.Row():
553
+ with gr.Column():
554
+ interview_topic = gr.Textbox(label="Topic", placeholder="Binary trees...")
555
+ with gr.Row():
556
+ interview_diff = gr.Dropdown(["Easy", "Medium", "Hard"], value="Medium")
557
+ interview_lang = gr.Dropdown(LANGUAGES[:8], value="Python")
558
+ interview_btn = gr.Button("🎓 Generate", variant="primary")
559
+ with gr.Column():
560
+ interview_output = gr.Markdown()
561
+
562
+ with gr.TabItem("🛠️ Builders"):
563
+ gr.Markdown("### 🗄️ SQL")
564
+ with gr.Row():
565
+ with gr.Column():
566
+ sql_desc = gr.Textbox(label="Describe", lines=2)
567
+ sql_type = gr.Dropdown(["PostgreSQL", "MySQL", "SQLite"], value="PostgreSQL")
568
+ sql_btn = gr.Button("🗄️ Build", variant="primary")
569
+ with gr.Column():
570
+ sql_output = gr.Code(language="sql", lines=6)
571
+
572
+ gr.Markdown("---\n### 🐚 Shell")
573
+ with gr.Row():
574
+ with gr.Column():
575
+ shell_desc = gr.Textbox(label="Describe", lines=2)
576
+ shell_type = gr.Dropdown(["Bash", "PowerShell", "Zsh"], value="Bash")
577
+ shell_btn = gr.Button("🐚 Build", variant="primary")
578
+ with gr.Column():
579
+ shell_output = gr.Code(language="bash", lines=6)
580
+
581
+ gr.Markdown("---\n### ⏰ Cron")
582
+ with gr.Row():
583
+ with gr.Column():
584
+ cron_desc = gr.Textbox(label="Describe", lines=2)
585
+ cron_btn = gr.Button("⏰ Build", variant="primary")
586
+ with gr.Column():
587
+ cron_output = gr.Markdown()
588
+
589
+ gr.Markdown("---\n### 🎯 Regex")
590
+ with gr.Row():
591
+ with gr.Column():
592
+ regex_desc = gr.Textbox(label="Describe", lines=2)
593
+ regex_btn = gr.Button("🎯 Build", variant="primary")
594
  with gr.Column():
595
  regex_output = gr.Markdown()
596
 
597
+ gr.Markdown("---\n### 🔗 API")
598
+ with gr.Row():
599
+ with gr.Column():
600
+ api_desc = gr.Textbox(label="Describe", lines=2)
601
+ api_fw = gr.Dropdown(["FastAPI", "Express", "Flask"], value="FastAPI")
602
+ api_btn = gr.Button("🔗 Build", variant="primary")
603
+ with gr.Column():
604
+ api_output = gr.Code(lines=8)
605
+
606
+ with gr.TabItem("📦 Data"):
607
+ gr.Markdown("### 📦 Mock Data")
608
+ with gr.Row():
609
+ with gr.Column():
610
+ mock_schema = gr.Textbox(label="Schema", lines=2, placeholder="User: name, email, age...")
611
+ with gr.Row():
612
+ mock_count = gr.Slider(1, 20, value=5, step=1, label="Count")
613
+ mock_format = gr.Dropdown(["JSON", "CSV", "SQL"], value="JSON")
614
+ mock_btn = gr.Button("📦 Generate", variant="primary")
615
+ with gr.Column():
616
+ mock_output = gr.Code(lines=10)
617
+
618
+ gr.Markdown("---\n### 🔄 Format Converter")
619
  with gr.Row():
620
  with gr.Column():
621
+ format_input = gr.Code(label="Input", lines=6)
622
+ with gr.Row():
623
+ format_from = gr.Dropdown(["JSON", "YAML", "XML", "CSV"], value="JSON")
624
+ format_to = gr.Dropdown(["JSON", "YAML", "XML", "CSV"], value="YAML")
625
+ format_btn = gr.Button("🔄 Convert", variant="primary")
626
  with gr.Column():
627
+ format_output = gr.Code(label="Output", lines=6)
628
 
629
+ gr.HTML('<div style="text-align:center;padding:16px;opacity:0.5;">🔥 Axon v6 llama.cpp Your Wheels Power This! 🛞</div>')
630
 
631
+ # ===== EVENTS =====
632
  def respond(message, history, model, temp, tokens):
633
  history = history or []
634
  for updated in chat_stream(message, history, model, temp, tokens):
 
639
  clear.click(lambda: [], None, chatbot)
640
  transcribe.click(transcribe_audio, audio, msg)
641
 
642
+ gen_btn.click(generate_stream, [gen_prompt, gen_lang, model_dropdown, gen_temp, max_tokens], gen_output)
 
 
643
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
644
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
645
  review_btn.click(review_code, [review_input, model_dropdown, max_tokens], review_output)
 
647
  test_btn.click(generate_tests, [test_input, test_lang, test_fw, model_dropdown, max_tokens], test_output)
648
  doc_btn.click(document_code, [doc_input, doc_lang, doc_style, model_dropdown, max_tokens], doc_output)
649
  opt_btn.click(optimize_code, [opt_input, opt_lang, opt_focus, model_dropdown, max_tokens], opt_output)
650
+
651
+ security_btn.click(security_scan, [security_input, model_dropdown, max_tokens], security_output)
652
+ complexity_btn.click(analyze_complexity, [complexity_input, model_dropdown, max_tokens], complexity_output)
653
+ diff_btn.click(code_diff, [diff_code1, diff_code2, model_dropdown, max_tokens], diff_output)
654
+ pseudo_btn.click(to_pseudocode, [pseudo_input, pseudo_type, model_dropdown, max_tokens], pseudo_output)
655
+ interview_btn.click(interview_challenge, [interview_topic, interview_diff, interview_lang, model_dropdown, max_tokens], interview_output)
656
+
657
+ sql_btn.click(build_sql, [sql_desc, sql_type, model_dropdown, max_tokens], sql_output)
658
+ shell_btn.click(build_shell, [shell_desc, shell_type, model_dropdown, max_tokens], shell_output)
659
+ cron_btn.click(build_cron, [cron_desc, model_dropdown, max_tokens], cron_output)
660
  regex_btn.click(build_regex, [regex_desc, model_dropdown, max_tokens], regex_output)
661
  api_btn.click(build_api, [api_desc, api_fw, model_dropdown, max_tokens], api_output)
662
+
663
+ mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
664
+ format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
665
 
666
+ # Preload default model
667
+ print("🔥 Preloading default model...")
668
+ load_model("Qwen2.5 Coder 3B (Fast)")
669
 
670
  demo.launch(server_name="0.0.0.0", server_port=7860)