AIencoder commited on
Commit
5c791ad
·
verified ·
1 Parent(s): 8350d8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -327
app.py CHANGED
@@ -3,55 +3,34 @@ import gradio as gr
3
  import json
4
  import time
5
  from datetime import datetime
6
- from pathlib import Path
7
  from llama_cpp import Llama
8
  from faster_whisper import WhisperModel
9
- from huggingface_hub import hf_hub_download # Added for auto-download
10
 
11
  # ===== CONFIG =====
12
- MODELS_DIR = "/data/models"
13
- MAX_TOKENS = 2048
14
  CONTEXT_SIZE = 4096
15
 
16
  MODEL_REPOS = {
17
- # 30B: Unsloth is the most reliable source for Qwen3 GGUFs currently
18
- "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf": "unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF",
19
-
20
- # 3B: Qwen actually has an official one, but bartowski is safer fallback
21
- "qwen2.5-coder-3b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-3B-Instruct-GGUF",
22
-
23
- # 7B: Official Qwen GGUF is often missing/broken. Bartowski is the go-to here.
24
  "qwen2.5-coder-7b-instruct-q4_k_m.gguf": "bartowski/Qwen2.5-Coder-7B-Instruct-GGUF",
25
-
26
- # 14B: Bartowski is recommended for consistency
27
- "qwen2.5-coder-14b-instruct-q4_k_m.gguf": "bartowski/Qwen2.5-Coder-14B-Instruct-GGUF",
28
-
29
- # DeepSeek: Definitely needs community repo
30
- "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf": "bartowski/DeepSeek-Coder-V2-Lite-Instruct-GGUF",
31
-
32
- # Tiny models
33
  "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF",
34
  "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF",
 
35
  }
36
 
37
  MODELS = {
38
- " Qwen3 Coder 30B-A3B (Best)": "Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf",
39
- "🏆 Qwen2.5 Coder 14B (Premium)": "qwen2.5-coder-14b-instruct-q4_k_m.gguf",
40
- "🧠 DeepSeek V2 Lite (Logic)": "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf",
41
  "⚖️ Qwen2.5 Coder 7B (Balanced)": "qwen2.5-coder-7b-instruct-q4_k_m.gguf",
42
  "🚀 Qwen2.5 Coder 3B (Fast)": "qwen2.5-coder-3b-instruct-q4_k_m.gguf",
43
- "⚡ DeepSeek Coder 6.7B": "deepseek-coder-6.7b-instruct.Q4_K_M.gguf",
44
  "💨 Qwen2.5 Coder 1.5B (Quick)": "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",
45
  "🔬 Qwen2.5 Coder 0.5B (Instant)": "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf",
46
  }
47
 
48
  MODEL_INFO = {
49
- " Qwen3 Coder 30B-A3B (Best)": "🏆 Best qualityMoE 30B/3B ~10GB",
50
- "🏆 Qwen2.5 Coder 14B (Premium)": "💎 Premium • ~8GB • Complex tasks",
51
- "🧠 DeepSeek V2 Lite (Logic)": "🧠 MoE 16B • ~9GB • Algorithms",
52
  "⚖️ Qwen2.5 Coder 7B (Balanced)": "⚖️ Balanced • ~4.5GB • Recommended",
53
  "🚀 Qwen2.5 Coder 3B (Fast)": "🚀 Fast • ~2GB • Great all-rounder",
54
- "⚡ DeepSeek Coder 6.7B": "⚡ Logic focused • ~4GB",
55
  "💨 Qwen2.5 Coder 1.5B (Quick)": "💨 Quick • ~1GB • Simple tasks",
56
  "🔬 Qwen2.5 Coder 0.5B (Instant)": "🔬 Instant • ~0.3GB • Lightning fast",
57
  }
@@ -83,20 +62,18 @@ def load_model(model_name):
83
 
84
  model_path = os.path.join(MODELS_DIR, filename)
85
 
86
- # --- AUTO DOWNLOAD LOGIC ---
87
  if not os.path.exists(model_path):
88
- print(f"⬇️ Model not found. Attempting download for {filename}...")
89
- repo_id = MODEL_REPOS.get(filename, "Qwen/Qwen2.5-Coder-3B-Instruct-GGUF") # Default fallback
90
- try:
91
- hf_hub_download(
92
- repo_id=repo_id,
93
- filename=filename,
94
- local_dir=MODELS_DIR,
95
- local_dir_use_symlinks=False
96
- )
97
- print("✅ Download complete!")
98
- except Exception as e:
99
- print(f"❌ Download failed: {e}")
100
  return None
101
 
102
  print(f"📥 Loading {model_name}...")
@@ -136,8 +113,8 @@ def get_status():
136
  available = [name for name, file in MODELS.items() if os.path.exists(os.path.join(MODELS_DIR, file))]
137
  if current_model_name:
138
  short = current_model_name.split('(')[0].strip().split()[-1]
139
- return f"🟢 Ready • {len(available)} models • Active: {short}"
140
- return f"🟡 {len(available)} models available"
141
 
142
  def get_model_info(model_name):
143
  return MODEL_INFO.get(model_name, "")
@@ -163,7 +140,7 @@ def transcribe_audio(audio):
163
  def generate_response(model_name, prompt, temperature=0.7, max_tokens=2048):
164
  llm = load_model(model_name)
165
  if not llm:
166
- return "❌ **Model not available.**"
167
 
168
  try:
169
  if "deepseek" in model_name.lower():
@@ -203,21 +180,15 @@ def extract_code(text):
203
  pass
204
  return text
205
 
206
- # ===== HISTORY FUNCTIONS =====
207
 
208
  def export_chat_history(history):
209
  if not history:
210
  return None, "⚠️ No chat history to export."
211
 
212
- export = {
213
- "exported_at": datetime.now().isoformat(),
214
- "tool": "Axon v6 Chat",
215
- "messages": history # Direct dump for Gradio 5 format
216
- }
217
-
218
  filename = f"/tmp/axon_chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
219
  with open(filename, "w") as f:
220
- json.dump(export, f, indent=2)
221
 
222
  return filename, f"✅ Exported {len(history)} messages!"
223
 
@@ -225,13 +196,7 @@ def export_code(code, language):
225
  if not code or not code.strip():
226
  return None, "⚠️ No code to export."
227
 
228
- ext_map = {
229
- "Python": "py", "JavaScript": "js", "TypeScript": "ts", "Go": "go",
230
- "Rust": "rs", "Java": "java", "C++": "cpp", "C#": "cs", "C": "c",
231
- "PHP": "php", "Ruby": "rb", "Swift": "swift", "Kotlin": "kt",
232
- "HTML/CSS": "html", "SQL": "sql", "Bash": "sh", "PowerShell": "ps1", "Lua": "lua"
233
- }
234
-
235
  ext = ext_map.get(language, "txt")
236
  filename = f"/tmp/axon_code_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{ext}"
237
 
@@ -240,7 +205,7 @@ def export_code(code, language):
240
 
241
  return filename, f"✅ Exported as .{ext}!"
242
 
243
- # ===== STREAMING (UPDATED FOR GRADIO 5) =====
244
 
245
  def chat_stream(message, history, model_name, temperature, max_tokens):
246
  history = history or []
@@ -262,18 +227,13 @@ def chat_stream(message, history, model_name, temperature, max_tokens):
262
  if "deepseek" in model_name.lower():
263
  conv = "### Instruction:\nYou are an expert coding assistant. Use markdown code blocks.\n\n"
264
  for msg in history:
265
- if msg['role'] == 'user':
266
- conv += f"User: {msg['content']}\n"
267
- else:
268
- conv += f"Assistant: {msg['content']}\n\n"
269
  conv += f"User: {message}\n\n### Response:\n"
270
  stop_tokens = ["### Instruction:", "User:"]
271
  else:
272
  conv = "<|im_start|>system\nYou are an expert coding assistant. Use markdown code blocks.<|im_end|>\n"
273
  for msg in history:
274
- role = msg['role']
275
- content = msg['content']
276
- conv += f"<|im_start|>{role}\n{content}<|im_end|>\n"
277
  conv += f"<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
278
  stop_tokens = ["<|im_end|>", "<|im_start|>"]
279
 
@@ -283,8 +243,7 @@ def chat_stream(message, history, model_name, temperature, max_tokens):
283
  try:
284
  full = ""
285
  for chunk in llm(conv, max_tokens=max_tokens, temperature=temperature, top_p=0.9, stop=stop_tokens, stream=True):
286
- text_chunk = chunk["choices"][0]["text"]
287
- full += text_chunk
288
  history[-1]['content'] = full
289
  yield history
290
  except Exception as e:
@@ -303,10 +262,10 @@ def generate_stream(prompt, language, model_name, temperature, max_tokens):
303
  return
304
 
305
  if "deepseek" in model_name.lower():
306
- formatted = f"### Instruction:\nWrite clean {language} code with comments:\n{prompt}\n\nOutput only code:\n\n### Response:\n"
307
  stop_tokens = ["### Instruction:"]
308
  else:
309
- 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"
310
  stop_tokens = ["<|im_end|>"]
311
 
312
  try:
@@ -317,236 +276,135 @@ def generate_stream(prompt, language, model_name, temperature, max_tokens):
317
  except Exception as e:
318
  yield f"❌ {str(e)[:50]}"
319
 
320
- # ===== CORE FEATURES =====
321
 
322
  def explain_code(code, model_name, detail, max_tokens):
323
  valid, err = validate_input(code, "Code")
324
- if not valid:
325
- return err
326
- prompts = {
327
- "Brief": f"Explain briefly (2-3 sentences):\n{code}",
328
- "Normal": f"Explain this code:\n{code}",
329
- "Detailed": f"Detailed explanation (purpose, logic, complexity, improvements):\n{code}"
330
- }
331
  return generate_response(model_name, prompts.get(detail, prompts["Normal"]), 0.5, max_tokens)
332
 
333
  def fix_code(code, error_msg, model_name, max_tokens):
334
  valid, err = validate_input(code, "Code")
335
- if not valid:
336
- return err
337
- e = error_msg.strip() if error_msg else "Not working"
338
- return generate_response(model_name, f"Fix this code. Error: {e}\n\n{code}\n\nFixed code and explanation:", 0.3, max_tokens)
339
 
340
  def review_code(code, model_name, max_tokens):
341
  valid, err = validate_input(code, "Code")
342
- if not valid:
343
- return err
344
  return generate_response(model_name, f"Review for bugs, performance, security:\n{code}", 0.4, max_tokens)
345
 
346
  def convert_code(code, from_lang, to_lang, model_name, max_tokens):
347
  valid, err = validate_input(code, "Code")
348
- if not valid:
349
- return err
350
- if from_lang == to_lang:
351
- return "⚠️ Same language."
352
  result = generate_response(model_name, f"Convert {from_lang} to {to_lang}. Code only:\n{code}", 0.3, max_tokens)
353
  return result if result.startswith("❌") else extract_code(result)
354
 
355
  def generate_tests(code, language, framework, model_name, max_tokens):
356
  valid, err = validate_input(code, "Code")
357
- if not valid:
358
- return err
359
- fw = framework.strip() if framework else "pytest"
360
- result = generate_response(model_name, f"Generate {fw} tests for {language}. Code only:\n{code}", 0.3, max_tokens)
361
  return result if result.startswith("❌") else extract_code(result)
362
 
363
  def document_code(code, language, style, model_name, max_tokens):
364
  valid, err = validate_input(code, "Code")
365
- if not valid:
366
- return err
367
  result = generate_response(model_name, f"Add {style.lower()} to this {language} code:\n{code}", 0.4, max_tokens)
368
  return result if style == "README" or result.startswith("❌") else extract_code(result)
369
 
370
  def optimize_code(code, language, focus, model_name, max_tokens):
371
  valid, err = validate_input(code, "Code")
372
- if not valid:
373
- return err
374
  return generate_response(model_name, f"Optimize {language} for {focus.lower()}. Explain:\n{code}", 0.3, max_tokens)
375
 
376
  def security_scan(code, model_name, max_tokens):
377
  valid, err = validate_input(code, "Code")
378
- if not valid:
379
- return err
380
- prompt = """Security audit this code. Check for:
381
- 1. Injection vulnerabilities (SQL, XSS, Command)
382
- 2. Authentication issues
383
- 3. Data exposure
384
- 4. Input validation
385
- 5. Cryptography issues
386
-
387
- For each issue: Severity (🔴🟠🟡🟢), Location, Description, Fix.
388
-
389
- Code:
390
- """ + code
391
- return generate_response(model_name, prompt, 0.3, max_tokens)
392
 
393
  def analyze_complexity(code, model_name, max_tokens):
394
  valid, err = validate_input(code, "Code")
395
- if not valid:
396
- return err
397
- prompt = """Analyze time and space complexity:
398
- 1. Time Complexity (Big O)
399
- 2. Space Complexity (Big O)
400
- 3. Best/Average/Worst cases
401
- 4. Bottlenecks
402
- 5. Optimization suggestions
403
-
404
- Code:
405
- """ + code
406
- return generate_response(model_name, prompt, 0.4, max_tokens)
407
 
408
  def build_sql(description, db_type, model_name, max_tokens):
409
  valid, err = validate_input(description, "Description")
410
- if not valid:
411
- return err
412
- result = generate_response(model_name, f"Write optimized {db_type} SQL for:\n{description}\n\nSQL only:", 0.2, max_tokens)
413
  return result if result.startswith("❌") else extract_code(result)
414
 
415
  def build_shell(description, shell_type, model_name, max_tokens):
416
  valid, err = validate_input(description, "Description")
417
- if not valid:
418
- return err
419
- result = generate_response(model_name, f"Write {shell_type} command for:\n{description}\n\nCommand only:", 0.2, max_tokens)
420
  return result if result.startswith("❌") else extract_code(result)
421
 
422
  def code_diff(code1, code2, model_name, max_tokens):
423
  v1, e1 = validate_input(code1, "Code 1")
424
  v2, e2 = validate_input(code2, "Code 2")
425
- if not v1:
426
- return e1
427
- if not v2:
428
- return e2
429
- prompt = f"""Compare these code snippets:
430
- 1. Key differences
431
- 2. Functionality changes
432
- 3. Performance impact
433
- 4. Which is better and why
434
-
435
- === CODE 1 ===
436
- {code1}
437
-
438
- === CODE 2 ===
439
- {code2}"""
440
- return generate_response(model_name, prompt, 0.4, max_tokens)
441
 
442
  def generate_mock_data(schema, count, format_type, model_name, max_tokens):
443
  valid, err = validate_input(schema, "Schema")
444
- if not valid:
445
- return err
446
- result = generate_response(model_name, f"Generate {count} realistic mock entries as {format_type}:\n{schema}", 0.7, max_tokens)
447
  return result if result.startswith("❌") else extract_code(result)
448
 
449
  def interview_challenge(topic, difficulty, language, model_name, max_tokens):
450
  valid, err = validate_input(topic, "Topic")
451
- if not valid:
452
- return err
453
- prompt = f"""Create {difficulty} {language} interview challenge about {topic}.
454
-
455
- Include:
456
- 1. Problem statement
457
- 2. Examples (2-3)
458
- 3. Constraints
459
- 4. Hints
460
- 5. Solution with explanation"""
461
- return generate_response(model_name, prompt, 0.6, max_tokens)
462
 
463
  def to_pseudocode(code, output_type, model_name, max_tokens):
464
  valid, err = validate_input(code, "Code")
465
- if not valid:
466
- return err
467
- if output_type == "Pseudocode":
468
- prompt = f"Convert to pseudocode:\n{code}"
469
- else:
470
- prompt = f"Create Mermaid.js flowchart for:\n{code}"
471
  return generate_response(model_name, prompt, 0.3, max_tokens)
472
 
473
  def build_cron(description, model_name, max_tokens):
474
  valid, err = validate_input(description, "Description")
475
- if not valid:
476
- return err
477
- return generate_response(model_name, f"Create cron expression for: {description}\n\nInclude: expression, breakdown, next 5 runs", 0.2, max_tokens)
478
 
479
  def build_regex(description, model_name, max_tokens):
480
  valid, err = validate_input(description, "Description")
481
- if not valid:
482
- return err
483
- return generate_response(model_name, f"Create regex for: {description}\n\nPattern, explanation, examples, Python code:", 0.3, max_tokens)
484
 
485
  def build_api(description, framework, model_name, max_tokens):
486
  valid, err = validate_input(description, "Description")
487
- if not valid:
488
- return err
489
- result = generate_response(model_name, f"Create {framework} REST endpoint:\n{description}\n\nCode:", 0.3, max_tokens)
490
  return result if result.startswith("❌") else extract_code(result)
491
 
492
  def convert_data_format(data, from_fmt, to_fmt, model_name, max_tokens):
493
  valid, err = validate_input(data, "Data")
494
- if not valid:
495
- return err
496
- if from_fmt == to_fmt:
497
- return "⚠️ Same format."
498
- result = generate_response(model_name, f"Convert {from_fmt} to {to_fmt}:\n{data}\n\nOutput only:", 0.1, max_tokens)
499
  return result if result.startswith("❌") else extract_code(result)
500
 
501
- # ===== THEME =====
502
-
503
- light_theme = gr.themes.Soft(
504
- primary_hue="indigo",
505
- secondary_hue="blue",
506
- )
507
-
508
- dark_theme = gr.themes.Soft(
509
- primary_hue="indigo",
510
- secondary_hue="blue",
511
- ).set(
512
- body_background_fill="#0f172a",
513
- body_background_fill_dark="#0f172a",
514
- block_background_fill="#1e293b",
515
- block_background_fill_dark="#1e293b",
516
- border_color_primary="#334155",
517
- border_color_primary_dark="#334155",
518
- )
519
-
520
  # ===== UI =====
521
 
522
- # FIX: Title and theme moved here
523
- with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
524
 
525
- # State for theme
526
- is_dark = gr.State(True)
527
-
528
- # Header
529
  gr.HTML("""
530
  <div style="background: linear-gradient(135deg, #6366f1, #8b5cf6, #06b6d4); border-radius: 16px; padding: 24px; margin-bottom: 16px;">
531
- <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;">
532
- <div>
533
- <h1 style="color: white; margin: 0; font-size: 2rem;">🔥 Axon v6</h1>
534
- <p style="color: rgba(255,255,255,0.9); margin: 4px 0 0 0;">AI Coding Assistant 8 Models • 19 Tools • 100% Local</p>
535
- </div>
536
- <div style="display: flex; gap: 8px; flex-wrap: wrap;">
537
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🤖 8 Models</span>
538
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🛠️ 19 Tools</span>
539
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">⚡ llama.cpp</span>
540
- </div>
541
  </div>
542
  </div>
543
  """)
544
 
545
- # Status row
546
- with gr.Row():
547
- status = gr.Markdown(value=get_status, every=5)
548
 
549
- # Settings
550
  with gr.Row():
551
  model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="🚀 Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
552
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
@@ -557,109 +415,66 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
557
 
558
  with gr.Tabs():
559
 
560
- # ===== HOME =====
561
  with gr.TabItem("🏠 Home"):
562
  gr.HTML("""
563
  <div style="padding: 20px;">
564
- <h2 style="margin-top: 0;">Welcome to Axon v6! 🔥</h2>
565
- <p>The ultimate free AI coding assistant - running 100% locally on your browser.</p>
566
-
567
  <h3>🚀 Quick Start</h3>
568
- <ol>
569
- <li><strong>Select a model</strong> from the dropdown above</li>
570
- <li><strong>Choose a tool</strong> from the tabs</li>
571
- <li><strong>Start coding!</strong></li>
572
- </ol>
573
-
574
  <h3>🤖 Models</h3>
575
- <table style="width: 100%; border-collapse: collapse;">
576
- <tr style="background: rgba(99, 102, 241, 0.2);">
577
- <th style="padding: 8px; text-align: left;">Model</th>
578
- <th style="padding: 8px; text-align: left;">Size</th>
579
- <th style="padding: 8px; text-align: left;">Best For</th>
580
- </tr>
581
- <tr><td style="padding: 8px;">⭐ Qwen3 30B-A3B</td><td>~10GB</td><td>Best quality (MoE)</td></tr>
582
- <tr><td style="padding: 8px;">🏆 Qwen2.5 14B</td><td>~8GB</td><td>Premium tasks</td></tr>
583
- <tr><td style="padding: 8px;">🧠 DeepSeek V2 Lite</td><td>~9GB</td><td>Complex logic</td></tr>
584
- <tr><td style="padding: 8px;">⚖️ Qwen2.5 7B</td><td>~4.5GB</td><td>Balanced</td></tr>
585
- <tr><td style="padding: 8px;">🚀 Qwen2.5 3B</td><td>~2GB</td><td>Fast & capable</td></tr>
586
- <tr><td style="padding: 8px;">⚡ DeepSeek 6.7B</td><td>~4GB</td><td>Algorithms</td></tr>
587
- <tr><td style="padding: 8px;">💨 Qwen2.5 1.5B</td><td>~1GB</td><td>Quick tasks</td></tr>
588
- <tr><td style="padding: 8px;">🔬 Qwen2.5 0.5B</td><td>~0.3GB</td><td>Instant</td></tr>
589
  </table>
590
-
591
- <h3>🛠️ 19 Tools Available</h3>
592
- <p>
593
- <strong>Core:</strong> Chat, Generate, Explain, Debug, Review<br>
594
- <strong>Advanced:</strong> Security, Complexity, Convert, Test, Document, Optimize, Diff, Pseudo, Interview<br>
595
- <strong>Builders:</strong> SQL, Shell, Cron, Regex, API<br>
596
- <strong>Data:</strong> Mock Data, Format Converter
597
- </p>
598
-
599
- <h3>🔗 Links</h3>
600
- <p>
601
- <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank">🛞 Pre-built Wheels</a> •
602
- <a href="https://github.com/ggerganov/llama.cpp" target="_blank">📦 llama.cpp</a> •
603
- <a href="https://huggingface.co/Qwen" target="_blank">🤖 Qwen Models</a>
604
- </p>
605
- </div>
606
- """)
607
-
608
- # Share buttons
609
- gr.HTML("""
610
- <div style="padding: 20px; border-top: 1px solid #334155;">
611
- <h3>📤 Share Axon</h3>
612
- <div style="display: flex; gap: 10px; flex-wrap: wrap;">
613
- <a href="https://twitter.com/intent/tweet?text=Check%20out%20Axon%20v6%20-%20Free%20AI%20Coding%20Assistant!%20🔥%208%20Models,%2019%20Tools,%20100%25%20Local&url=https://huggingface.co/spaces/AIencoder/Axon" target="_blank" style="background: #1DA1F2; color: white; padding: 8px 16px; border-radius: 8px; text-decoration: none;">🐦 Twitter</a>
614
- <a href="https://www.reddit.com/submit?url=https://huggingface.co/spaces/AIencoder/Axon&title=Axon%20v6%20-%20Free%20AI%20Coding%20Assistant%20with%208%20Models%20and%2019%20Tools" target="_blank" style="background: #FF4500; color: white; padding: 8px 16px; border-radius: 8px; text-decoration: none;">🤖 Reddit</a>
615
- <a href="https://www.linkedin.com/sharing/share-offsite/?url=https://huggingface.co/spaces/AIencoder/Axon" target="_blank" style="background: #0A66C2; color: white; padding: 8px 16px; border-radius: 8px; text-decoration: none;">💼 LinkedIn</a>
616
- <a href="https://huggingface.co/spaces/AIencoder/Axon" target="_blank" style="background: #FFD21E; color: black; padding: 8px 16px; border-radius: 8px; text-decoration: none;">🤗 HuggingFace</a>
617
  </div>
618
  </div>
619
  """)
620
 
621
- # ===== CHAT =====
622
  with gr.TabItem("💬 Chat"):
623
- chatbot = gr.Chatbot(height=400) # Removed type="messages"
624
  with gr.Row():
625
  msg = gr.Textbox(placeholder="Ask anything...", show_label=False, scale=8)
626
  send = gr.Button("Send", variant="primary", scale=1)
627
  with gr.Row():
628
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
629
- transcribe = gr.Button("🎤 Transcribe", scale=1)
630
- clear = gr.Button("🗑️ Clear", scale=1)
631
- export_chat_btn = gr.Button("💾 Export", scale=1)
632
-
633
- chat_export_file = gr.File(label="Download", visible=False)
634
  chat_export_status = gr.Markdown("")
635
 
636
- # ===== GENERATE =====
637
  with gr.TabItem("⚡ Generate"):
638
  with gr.Row():
639
  with gr.Column():
640
  gen_prompt = gr.Textbox(label="📝 Describe", lines=3)
641
- with gr.Row():
642
- gen_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
643
- gen_temp = gr.Slider(0, 1, value=0.3, step=0.1, label="🌡️")
644
  gen_btn = gr.Button("⚡ Generate", variant="primary")
645
  with gr.Column():
646
  gen_output = gr.Code(label="Code", language="python", lines=14)
647
- with gr.Row():
648
- gen_export_btn = gr.Button("💾 Export Code")
649
- gen_export_status = gr.Markdown("")
650
- gen_export_file = gr.File(label="Download", visible=False)
651
 
652
- # ===== EXPLAIN =====
653
  with gr.TabItem("🔍 Explain"):
654
  with gr.Row():
655
- with gr.Column(): # FIXED: used to be Column()
656
  explain_input = gr.Code(label="Code", lines=10)
657
  explain_detail = gr.Radio(["Brief", "Normal", "Detailed"], value="Normal")
658
  explain_btn = gr.Button("🔍 Explain", variant="primary")
659
  with gr.Column():
660
  explain_output = gr.Markdown()
661
 
662
- # ===== DEBUG =====
663
  with gr.TabItem("🔧 Debug"):
664
  with gr.Row():
665
  with gr.Column():
@@ -669,7 +484,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
669
  with gr.Column():
670
  fix_output = gr.Markdown()
671
 
672
- # ===== REVIEW =====
673
  with gr.TabItem("📋 Review"):
674
  with gr.Row():
675
  with gr.Column():
@@ -678,7 +492,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
678
  with gr.Column():
679
  review_output = gr.Markdown()
680
 
681
- # ===== SECURITY =====
682
  with gr.TabItem("🔐 Security"):
683
  with gr.Row():
684
  with gr.Column():
@@ -687,7 +500,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
687
  with gr.Column():
688
  security_output = gr.Markdown()
689
 
690
- # ===== COMPLEXITY =====
691
  with gr.TabItem("📊 Complexity"):
692
  with gr.Row():
693
  with gr.Column():
@@ -696,7 +508,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
696
  with gr.Column():
697
  complexity_output = gr.Markdown()
698
 
699
- # ===== CONVERT =====
700
  with gr.TabItem("🔄 Convert"):
701
  with gr.Row():
702
  with gr.Column():
@@ -708,7 +519,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
708
  with gr.Column():
709
  convert_output = gr.Code(label="Result", lines=10)
710
 
711
- # ===== TEST =====
712
  with gr.TabItem("🧪 Test"):
713
  with gr.Row():
714
  with gr.Column():
@@ -720,7 +530,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
720
  with gr.Column():
721
  test_output = gr.Code(label="Tests", lines=10)
722
 
723
- # ===== DOCUMENT =====
724
  with gr.TabItem("📝 Document"):
725
  with gr.Row():
726
  with gr.Column():
@@ -732,7 +541,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
732
  with gr.Column():
733
  doc_output = gr.Code(label="Documented", lines=10)
734
 
735
- # ===== OPTIMIZE =====
736
  with gr.TabItem("🚀 Optimize"):
737
  with gr.Row():
738
  with gr.Column():
@@ -744,7 +552,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
744
  with gr.Column():
745
  opt_output = gr.Markdown()
746
 
747
- # ===== DIFF =====
748
  with gr.TabItem("🔀 Diff"):
749
  with gr.Row():
750
  with gr.Column():
@@ -754,7 +561,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
754
  with gr.Column():
755
  diff_output = gr.Markdown()
756
 
757
- # ===== PSEUDOCODE =====
758
  with gr.TabItem("📐 Pseudo"):
759
  with gr.Row():
760
  with gr.Column():
@@ -764,7 +570,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
764
  with gr.Column():
765
  pseudo_output = gr.Markdown()
766
 
767
- # ===== INTERVIEW =====
768
  with gr.TabItem("🎓 Interview"):
769
  with gr.Row():
770
  with gr.Column():
@@ -776,7 +581,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
776
  with gr.Column():
777
  interview_output = gr.Markdown()
778
 
779
- # ===== BUILDERS =====
780
  with gr.TabItem("🛠️ Builders"):
781
  gr.Markdown("### 🗄️ SQL")
782
  with gr.Row():
@@ -787,7 +591,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
787
  with gr.Column():
788
  sql_output = gr.Code(lines=6)
789
 
790
- gr.Markdown("---\n### 🐚 Shell")
791
  with gr.Row():
792
  with gr.Column():
793
  shell_desc = gr.Textbox(label="Describe", lines=2)
@@ -796,7 +600,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
796
  with gr.Column():
797
  shell_output = gr.Code(lines=6)
798
 
799
- gr.Markdown("---\n### ⏰ Cron")
800
  with gr.Row():
801
  with gr.Column():
802
  cron_desc = gr.Textbox(label="Describe", lines=2)
@@ -804,7 +608,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
804
  with gr.Column():
805
  cron_output = gr.Markdown()
806
 
807
- gr.Markdown("---\n### 🎯 Regex")
808
  with gr.Row():
809
  with gr.Column():
810
  regex_desc = gr.Textbox(label="Describe", lines=2)
@@ -812,7 +616,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
812
  with gr.Column():
813
  regex_output = gr.Markdown()
814
 
815
- gr.Markdown("---\n### 🔗 API")
816
  with gr.Row():
817
  with gr.Column():
818
  api_desc = gr.Textbox(label="Describe", lines=2)
@@ -821,7 +625,6 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
821
  with gr.Column():
822
  api_output = gr.Code(lines=8)
823
 
824
- # ===== DATA =====
825
  with gr.TabItem("📦 Data"):
826
  gr.Markdown("### 📦 Mock Data")
827
  with gr.Row():
@@ -834,7 +637,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
834
  with gr.Column():
835
  mock_output = gr.Code(lines=10)
836
 
837
- gr.Markdown("---\n### 🔄 Format Converter")
838
  with gr.Row():
839
  with gr.Column():
840
  format_input = gr.Code(label="Input", lines=6)
@@ -845,30 +648,18 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
845
  with gr.Column():
846
  format_output = gr.Code(label="Output", lines=6)
847
 
848
- # Footer
849
- gr.HTML("""
850
- <div style="text-align:center;padding:16px;border-top:1px solid #334155;margin-top:20px;">
851
- <p style="opacity:0.7;">🔥 Axon v6 • Built with ❤️ by <a href="https://huggingface.co/AIencoder" target="_blank" style="color:#8b5cf6;">AIencoder</a></p>
852
- <p style="opacity:0.5;font-size:0.8rem;">
853
- Wheels: <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank" style="color:#8b5cf6;">AIencoder/llama-cpp-wheels</a> •
854
- Powered by <a href="https://github.com/ggerganov/llama.cpp" target="_blank" style="color:#8b5cf6;">llama.cpp</a>
855
- </p>
856
- </div>
857
- """)
858
 
859
- # ===== EVENTS =====
860
-
861
  def respond(message, history, model, temp, tokens):
862
- # Gradio 5 automatically handles history state
863
  for updated in chat_stream(message, history, model, temp, tokens):
864
  yield updated, ""
865
 
866
  msg.submit(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
867
  send.click(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
868
  clear.click(lambda: [], None, chatbot)
869
- transcribe.click(transcribe_audio, audio, msg)
870
 
871
- # Export handlers
872
  def handle_chat_export(history):
873
  file, status = export_chat_history(history)
874
  return gr.update(value=file, visible=file is not None), status
@@ -880,7 +671,7 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
880
  export_chat_btn.click(handle_chat_export, chatbot, [chat_export_file, chat_export_status])
881
  gen_export_btn.click(handle_code_export, [gen_output, gen_lang], [gen_export_file, gen_export_status])
882
 
883
- gen_btn.click(generate_stream, [gen_prompt, gen_lang, model_dropdown, gen_temp, max_tokens], gen_output)
884
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
885
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
886
  review_btn.click(review_code, [review_input, model_dropdown, max_tokens], review_output)
@@ -888,25 +679,18 @@ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
888
  test_btn.click(generate_tests, [test_input, test_lang, test_fw, model_dropdown, max_tokens], test_output)
889
  doc_btn.click(document_code, [doc_input, doc_lang, doc_style, model_dropdown, max_tokens], doc_output)
890
  opt_btn.click(optimize_code, [opt_input, opt_lang, opt_focus, model_dropdown, max_tokens], opt_output)
891
-
892
  security_btn.click(security_scan, [security_input, model_dropdown, max_tokens], security_output)
893
  complexity_btn.click(analyze_complexity, [complexity_input, model_dropdown, max_tokens], complexity_output)
894
  diff_btn.click(code_diff, [diff_code1, diff_code2, model_dropdown, max_tokens], diff_output)
895
  pseudo_btn.click(to_pseudocode, [pseudo_input, pseudo_type, model_dropdown, max_tokens], pseudo_output)
896
  interview_btn.click(interview_challenge, [interview_topic, interview_diff, interview_lang, model_dropdown, max_tokens], interview_output)
897
-
898
  sql_btn.click(build_sql, [sql_desc, sql_type, model_dropdown, max_tokens], sql_output)
899
  shell_btn.click(build_shell, [shell_desc, shell_type, model_dropdown, max_tokens], shell_output)
900
  cron_btn.click(build_cron, [cron_desc, model_dropdown, max_tokens], cron_output)
901
  regex_btn.click(build_regex, [regex_desc, model_dropdown, max_tokens], regex_output)
902
  api_btn.click(build_api, [api_desc, api_fw, model_dropdown, max_tokens], api_output)
903
-
904
  mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
905
  format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
906
 
907
- # Preload
908
- print("🔥 Preloading model...")
909
- load_model("🚀 Qwen2.5 Coder 3B (Fast)")
910
-
911
- # Launch (Removed 'title' and 'theme', they are in Blocks)
912
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
3
  import json
4
  import time
5
  from datetime import datetime
 
6
  from llama_cpp import Llama
7
  from faster_whisper import WhisperModel
8
+ from huggingface_hub import hf_hub_download
9
 
10
  # ===== CONFIG =====
11
+ MODELS_DIR = "/models"
 
12
  CONTEXT_SIZE = 4096
13
 
14
  MODEL_REPOS = {
 
 
 
 
 
 
 
15
  "qwen2.5-coder-7b-instruct-q4_k_m.gguf": "bartowski/Qwen2.5-Coder-7B-Instruct-GGUF",
16
+ "qwen2.5-coder-3b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-3B-Instruct-GGUF",
 
 
 
 
 
 
 
17
  "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF",
18
  "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF",
19
+ "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf": "bartowski/DeepSeek-Coder-V2-Lite-Instruct-GGUF",
20
  }
21
 
22
  MODELS = {
23
+ "🧠 DeepSeek V2 Lite (Best)": "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf",
 
 
24
  "⚖️ Qwen2.5 Coder 7B (Balanced)": "qwen2.5-coder-7b-instruct-q4_k_m.gguf",
25
  "🚀 Qwen2.5 Coder 3B (Fast)": "qwen2.5-coder-3b-instruct-q4_k_m.gguf",
 
26
  "💨 Qwen2.5 Coder 1.5B (Quick)": "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",
27
  "🔬 Qwen2.5 Coder 0.5B (Instant)": "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf",
28
  }
29
 
30
  MODEL_INFO = {
31
+ "🧠 DeepSeek V2 Lite (Best)": "🏆 MoE 16B~9GBBest quality",
 
 
32
  "⚖️ Qwen2.5 Coder 7B (Balanced)": "⚖️ Balanced • ~4.5GB • Recommended",
33
  "🚀 Qwen2.5 Coder 3B (Fast)": "🚀 Fast • ~2GB • Great all-rounder",
 
34
  "💨 Qwen2.5 Coder 1.5B (Quick)": "💨 Quick • ~1GB • Simple tasks",
35
  "🔬 Qwen2.5 Coder 0.5B (Instant)": "🔬 Instant • ~0.3GB • Lightning fast",
36
  }
 
62
 
63
  model_path = os.path.join(MODELS_DIR, filename)
64
 
65
+ # Auto-download if needed
66
  if not os.path.exists(model_path):
67
+ repo_id = MODEL_REPOS.get(filename)
68
+ if repo_id:
69
+ print(f"⬇️ Downloading {filename}...")
70
+ try:
71
+ hf_hub_download(repo_id=repo_id, filename=filename, local_dir=MODELS_DIR)
72
+ print(f"✅ Downloaded {filename}")
73
+ except Exception as e:
74
+ print(f"❌ Download failed: {e}")
75
+ return None
76
+ else:
 
 
77
  return None
78
 
79
  print(f"📥 Loading {model_name}...")
 
113
  available = [name for name, file in MODELS.items() if os.path.exists(os.path.join(MODELS_DIR, file))]
114
  if current_model_name:
115
  short = current_model_name.split('(')[0].strip().split()[-1]
116
+ return f"🟢 Ready • {len(available)}/{len(MODELS)} cached • Active: {short}"
117
+ return f"🟡 {len(available)}/{len(MODELS)} models cached"
118
 
119
  def get_model_info(model_name):
120
  return MODEL_INFO.get(model_name, "")
 
140
  def generate_response(model_name, prompt, temperature=0.7, max_tokens=2048):
141
  llm = load_model(model_name)
142
  if not llm:
143
+ return "❌ **Model not available.** Try selecting a different model."
144
 
145
  try:
146
  if "deepseek" in model_name.lower():
 
180
  pass
181
  return text
182
 
183
+ # ===== HISTORY =====
184
 
185
  def export_chat_history(history):
186
  if not history:
187
  return None, "⚠️ No chat history to export."
188
 
 
 
 
 
 
 
189
  filename = f"/tmp/axon_chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
190
  with open(filename, "w") as f:
191
+ json.dump({"exported_at": datetime.now().isoformat(), "messages": history}, f, indent=2)
192
 
193
  return filename, f"✅ Exported {len(history)} messages!"
194
 
 
196
  if not code or not code.strip():
197
  return None, "⚠️ No code to export."
198
 
199
+ ext_map = {"Python": "py", "JavaScript": "js", "TypeScript": "ts", "Go": "go", "Rust": "rs", "Java": "java", "C++": "cpp", "C#": "cs", "C": "c", "PHP": "php", "Ruby": "rb", "Swift": "swift", "Kotlin": "kt", "HTML/CSS": "html", "SQL": "sql", "Bash": "sh", "PowerShell": "ps1", "Lua": "lua"}
 
 
 
 
 
 
200
  ext = ext_map.get(language, "txt")
201
  filename = f"/tmp/axon_code_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{ext}"
202
 
 
205
 
206
  return filename, f"✅ Exported as .{ext}!"
207
 
208
+ # ===== STREAMING =====
209
 
210
  def chat_stream(message, history, model_name, temperature, max_tokens):
211
  history = history or []
 
227
  if "deepseek" in model_name.lower():
228
  conv = "### Instruction:\nYou are an expert coding assistant. Use markdown code blocks.\n\n"
229
  for msg in history:
230
+ conv += f"{'User' if msg['role']=='user' else 'Assistant'}: {msg['content']}\n\n"
 
 
 
231
  conv += f"User: {message}\n\n### Response:\n"
232
  stop_tokens = ["### Instruction:", "User:"]
233
  else:
234
  conv = "<|im_start|>system\nYou are an expert coding assistant. Use markdown code blocks.<|im_end|>\n"
235
  for msg in history:
236
+ conv += f"<|im_start|>{msg['role']}\n{msg['content']}<|im_end|>\n"
 
 
237
  conv += f"<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
238
  stop_tokens = ["<|im_end|>", "<|im_start|>"]
239
 
 
243
  try:
244
  full = ""
245
  for chunk in llm(conv, max_tokens=max_tokens, temperature=temperature, top_p=0.9, stop=stop_tokens, stream=True):
246
+ full += chunk["choices"][0]["text"]
 
247
  history[-1]['content'] = full
248
  yield history
249
  except Exception as e:
 
262
  return
263
 
264
  if "deepseek" in model_name.lower():
265
+ formatted = f"### Instruction:\nWrite clean {language} code with comments:\n{prompt}\n\n### Response:\n"
266
  stop_tokens = ["### Instruction:"]
267
  else:
268
+ formatted = f"<|im_start|>system\nYou are an expert coder.<|im_end|>\n<|im_start|>user\nWrite clean {language} code with comments:\n{prompt}<|im_end|>\n<|im_start|>assistant\n"
269
  stop_tokens = ["<|im_end|>"]
270
 
271
  try:
 
276
  except Exception as e:
277
  yield f"❌ {str(e)[:50]}"
278
 
279
+ # ===== FEATURES =====
280
 
281
  def explain_code(code, model_name, detail, max_tokens):
282
  valid, err = validate_input(code, "Code")
283
+ if not valid: return err
284
+ prompts = {"Brief": f"Explain briefly:\n{code}", "Normal": f"Explain this code:\n{code}", "Detailed": f"Detailed explanation:\n{code}"}
 
 
 
 
 
285
  return generate_response(model_name, prompts.get(detail, prompts["Normal"]), 0.5, max_tokens)
286
 
287
  def fix_code(code, error_msg, model_name, max_tokens):
288
  valid, err = validate_input(code, "Code")
289
+ if not valid: return err
290
+ return generate_response(model_name, f"Fix this code. Error: {error_msg or 'Not working'}\n\n{code}", 0.3, max_tokens)
 
 
291
 
292
  def review_code(code, model_name, max_tokens):
293
  valid, err = validate_input(code, "Code")
294
+ if not valid: return err
 
295
  return generate_response(model_name, f"Review for bugs, performance, security:\n{code}", 0.4, max_tokens)
296
 
297
  def convert_code(code, from_lang, to_lang, model_name, max_tokens):
298
  valid, err = validate_input(code, "Code")
299
+ if not valid: return err
300
+ if from_lang == to_lang: return "⚠️ Same language."
 
 
301
  result = generate_response(model_name, f"Convert {from_lang} to {to_lang}. Code only:\n{code}", 0.3, max_tokens)
302
  return result if result.startswith("❌") else extract_code(result)
303
 
304
  def generate_tests(code, language, framework, model_name, max_tokens):
305
  valid, err = validate_input(code, "Code")
306
+ if not valid: return err
307
+ result = generate_response(model_name, f"Generate {framework or 'pytest'} tests for {language}:\n{code}", 0.3, max_tokens)
 
 
308
  return result if result.startswith("❌") else extract_code(result)
309
 
310
  def document_code(code, language, style, model_name, max_tokens):
311
  valid, err = validate_input(code, "Code")
312
+ if not valid: return err
 
313
  result = generate_response(model_name, f"Add {style.lower()} to this {language} code:\n{code}", 0.4, max_tokens)
314
  return result if style == "README" or result.startswith("❌") else extract_code(result)
315
 
316
  def optimize_code(code, language, focus, model_name, max_tokens):
317
  valid, err = validate_input(code, "Code")
318
+ if not valid: return err
 
319
  return generate_response(model_name, f"Optimize {language} for {focus.lower()}. Explain:\n{code}", 0.3, max_tokens)
320
 
321
  def security_scan(code, model_name, max_tokens):
322
  valid, err = validate_input(code, "Code")
323
+ if not valid: return err
324
+ return generate_response(model_name, f"Security audit. Check for injection, auth issues, data exposure, input validation. For each: Severity, Location, Fix.\n\nCode:\n{code}", 0.3, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
  def analyze_complexity(code, model_name, max_tokens):
327
  valid, err = validate_input(code, "Code")
328
+ if not valid: return err
329
+ return generate_response(model_name, f"Analyze time/space complexity (Big O), bottlenecks, optimizations:\n{code}", 0.4, max_tokens)
 
 
 
 
 
 
 
 
 
 
330
 
331
  def build_sql(description, db_type, model_name, max_tokens):
332
  valid, err = validate_input(description, "Description")
333
+ if not valid: return err
334
+ result = generate_response(model_name, f"Write {db_type} SQL for:\n{description}", 0.2, max_tokens)
 
335
  return result if result.startswith("❌") else extract_code(result)
336
 
337
  def build_shell(description, shell_type, model_name, max_tokens):
338
  valid, err = validate_input(description, "Description")
339
+ if not valid: return err
340
+ result = generate_response(model_name, f"Write {shell_type} command for:\n{description}", 0.2, max_tokens)
 
341
  return result if result.startswith("❌") else extract_code(result)
342
 
343
  def code_diff(code1, code2, model_name, max_tokens):
344
  v1, e1 = validate_input(code1, "Code 1")
345
  v2, e2 = validate_input(code2, "Code 2")
346
+ if not v1: return e1
347
+ if not v2: return e2
348
+ return generate_response(model_name, f"Compare:\n=== CODE 1 ===\n{code1}\n\n=== CODE 2 ===\n{code2}", 0.4, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
349
 
350
  def generate_mock_data(schema, count, format_type, model_name, max_tokens):
351
  valid, err = validate_input(schema, "Schema")
352
+ if not valid: return err
353
+ result = generate_response(model_name, f"Generate {count} mock entries as {format_type}:\n{schema}", 0.7, max_tokens)
 
354
  return result if result.startswith("❌") else extract_code(result)
355
 
356
  def interview_challenge(topic, difficulty, language, model_name, max_tokens):
357
  valid, err = validate_input(topic, "Topic")
358
+ if not valid: return err
359
+ return generate_response(model_name, f"Create {difficulty} {language} interview challenge about {topic}. Include problem, examples, constraints, hints, solution.", 0.6, max_tokens)
 
 
 
 
 
 
 
 
 
360
 
361
  def to_pseudocode(code, output_type, model_name, max_tokens):
362
  valid, err = validate_input(code, "Code")
363
+ if not valid: return err
364
+ prompt = f"Convert to pseudocode:\n{code}" if output_type == "Pseudocode" else f"Create Mermaid flowchart:\n{code}"
 
 
 
 
365
  return generate_response(model_name, prompt, 0.3, max_tokens)
366
 
367
  def build_cron(description, model_name, max_tokens):
368
  valid, err = validate_input(description, "Description")
369
+ if not valid: return err
370
+ return generate_response(model_name, f"Create cron expression for: {description}\nInclude: expression, breakdown, next 5 runs", 0.2, max_tokens)
 
371
 
372
  def build_regex(description, model_name, max_tokens):
373
  valid, err = validate_input(description, "Description")
374
+ if not valid: return err
375
+ return generate_response(model_name, f"Create regex for: {description}\nPattern, explanation, examples, Python code:", 0.3, max_tokens)
 
376
 
377
  def build_api(description, framework, model_name, max_tokens):
378
  valid, err = validate_input(description, "Description")
379
+ if not valid: return err
380
+ result = generate_response(model_name, f"Create {framework} REST endpoint:\n{description}", 0.3, max_tokens)
 
381
  return result if result.startswith("❌") else extract_code(result)
382
 
383
  def convert_data_format(data, from_fmt, to_fmt, model_name, max_tokens):
384
  valid, err = validate_input(data, "Data")
385
+ if not valid: return err
386
+ if from_fmt == to_fmt: return "⚠️ Same format."
387
+ result = generate_response(model_name, f"Convert {from_fmt} to {to_fmt}:\n{data}", 0.1, max_tokens)
 
 
388
  return result if result.startswith("❌") else extract_code(result)
389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  # ===== UI =====
391
 
392
+ with gr.Blocks(title="Axon v6", theme=gr.themes.Soft(primary_hue="indigo")) as demo:
 
393
 
 
 
 
 
394
  gr.HTML("""
395
  <div style="background: linear-gradient(135deg, #6366f1, #8b5cf6, #06b6d4); border-radius: 16px; padding: 24px; margin-bottom: 16px;">
396
+ <h1 style="color: white; margin: 0; font-size: 2rem;">🔥 Axon v6</h1>
397
+ <p style="color: rgba(255,255,255,0.9); margin: 4px 0 0 0;">AI Coding Assistant • 5 Models • 19 Tools • 100% Local</p>
398
+ <div style="display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap;">
399
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🤖 5 Models</span>
400
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🛠️ 19 Tools</span>
401
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">⚡ llama.cpp</span>
 
 
 
 
402
  </div>
403
  </div>
404
  """)
405
 
406
+ status = gr.Markdown(value=get_status, every=5)
 
 
407
 
 
408
  with gr.Row():
409
  model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="🚀 Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
410
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
 
415
 
416
  with gr.Tabs():
417
 
 
418
  with gr.TabItem("🏠 Home"):
419
  gr.HTML("""
420
  <div style="padding: 20px;">
421
+ <h2>Welcome to Axon v6! 🔥</h2>
422
+ <p>Free AI coding assistant - 100% local, no API keys.</p>
 
423
  <h3>🚀 Quick Start</h3>
424
+ <ol><li>Select a model</li><li>Choose a tool</li><li>Start coding!</li></ol>
425
+ <p><em>Models download automatically on first use</em></p>
 
 
 
 
426
  <h3>🤖 Models</h3>
427
+ <table style="width:100%;border-collapse:collapse;">
428
+ <tr style="background:rgba(99,102,241,0.2);"><th style="padding:8px;text-align:left;">Model</th><th>Size</th><th>Best For</th></tr>
429
+ <tr><td style="padding:8px;">🧠 DeepSeek V2 Lite</td><td>~9GB</td><td>Best quality</td></tr>
430
+ <tr><td style="padding:8px;">⚖️ Qwen2.5 7B</td><td>~4.5GB</td><td>Balanced</td></tr>
431
+ <tr><td style="padding:8px;">🚀 Qwen2.5 3B</td><td>~2GB</td><td>Fast</td></tr>
432
+ <tr><td style="padding:8px;">💨 Qwen2.5 1.5B</td><td>~1GB</td><td>Quick</td></tr>
433
+ <tr><td style="padding:8px;">🔬 Qwen2.5 0.5B</td><td>~0.3GB</td><td>Instant</td></tr>
 
 
 
 
 
 
 
434
  </table>
435
+ <h3>📤 Share</h3>
436
+ <div style="display:flex;gap:10px;flex-wrap:wrap;">
437
+ <a href="https://twitter.com/intent/tweet?text=Check%20out%20Axon%20v6!&url=https://huggingface.co/spaces/AIencoder/Axon" target="_blank" style="background:#1DA1F2;color:white;padding:8px 16px;border-radius:8px;text-decoration:none;">🐦 Twitter</a>
438
+ <a href="https://www.reddit.com/submit?url=https://huggingface.co/spaces/AIencoder/Axon&title=Axon%20v6" target="_blank" style="background:#FF4500;color:white;padding:8px 16px;border-radius:8px;text-decoration:none;">🤖 Reddit</a>
439
+ <a href="https://www.linkedin.com/sharing/share-offsite/?url=https://huggingface.co/spaces/AIencoder/Axon" target="_blank" style="background:#0A66C2;color:white;padding:8px 16px;border-radius:8px;text-decoration:none;">💼 LinkedIn</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  </div>
441
  </div>
442
  """)
443
 
 
444
  with gr.TabItem("💬 Chat"):
445
+ chatbot = gr.Chatbot(height=400, type="messages")
446
  with gr.Row():
447
  msg = gr.Textbox(placeholder="Ask anything...", show_label=False, scale=8)
448
  send = gr.Button("Send", variant="primary", scale=1)
449
  with gr.Row():
450
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
451
+ transcribe_btn = gr.Button("🎤", scale=1)
452
+ clear = gr.Button("🗑️", scale=1)
453
+ export_chat_btn = gr.Button("💾", scale=1)
454
+ chat_export_file = gr.File(visible=False)
 
455
  chat_export_status = gr.Markdown("")
456
 
 
457
  with gr.TabItem("⚡ Generate"):
458
  with gr.Row():
459
  with gr.Column():
460
  gen_prompt = gr.Textbox(label="📝 Describe", lines=3)
461
+ gen_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
 
 
462
  gen_btn = gr.Button("⚡ Generate", variant="primary")
463
  with gr.Column():
464
  gen_output = gr.Code(label="Code", language="python", lines=14)
465
+ gen_export_btn = gr.Button("💾 Export")
466
+ gen_export_file = gr.File(visible=False)
467
+ gen_export_status = gr.Markdown("")
 
468
 
 
469
  with gr.TabItem("🔍 Explain"):
470
  with gr.Row():
471
+ with gr.Column():
472
  explain_input = gr.Code(label="Code", lines=10)
473
  explain_detail = gr.Radio(["Brief", "Normal", "Detailed"], value="Normal")
474
  explain_btn = gr.Button("🔍 Explain", variant="primary")
475
  with gr.Column():
476
  explain_output = gr.Markdown()
477
 
 
478
  with gr.TabItem("🔧 Debug"):
479
  with gr.Row():
480
  with gr.Column():
 
484
  with gr.Column():
485
  fix_output = gr.Markdown()
486
 
 
487
  with gr.TabItem("📋 Review"):
488
  with gr.Row():
489
  with gr.Column():
 
492
  with gr.Column():
493
  review_output = gr.Markdown()
494
 
 
495
  with gr.TabItem("🔐 Security"):
496
  with gr.Row():
497
  with gr.Column():
 
500
  with gr.Column():
501
  security_output = gr.Markdown()
502
 
 
503
  with gr.TabItem("📊 Complexity"):
504
  with gr.Row():
505
  with gr.Column():
 
508
  with gr.Column():
509
  complexity_output = gr.Markdown()
510
 
 
511
  with gr.TabItem("🔄 Convert"):
512
  with gr.Row():
513
  with gr.Column():
 
519
  with gr.Column():
520
  convert_output = gr.Code(label="Result", lines=10)
521
 
 
522
  with gr.TabItem("🧪 Test"):
523
  with gr.Row():
524
  with gr.Column():
 
530
  with gr.Column():
531
  test_output = gr.Code(label="Tests", lines=10)
532
 
 
533
  with gr.TabItem("📝 Document"):
534
  with gr.Row():
535
  with gr.Column():
 
541
  with gr.Column():
542
  doc_output = gr.Code(label="Documented", lines=10)
543
 
 
544
  with gr.TabItem("🚀 Optimize"):
545
  with gr.Row():
546
  with gr.Column():
 
552
  with gr.Column():
553
  opt_output = gr.Markdown()
554
 
 
555
  with gr.TabItem("🔀 Diff"):
556
  with gr.Row():
557
  with gr.Column():
 
561
  with gr.Column():
562
  diff_output = gr.Markdown()
563
 
 
564
  with gr.TabItem("📐 Pseudo"):
565
  with gr.Row():
566
  with gr.Column():
 
570
  with gr.Column():
571
  pseudo_output = gr.Markdown()
572
 
 
573
  with gr.TabItem("🎓 Interview"):
574
  with gr.Row():
575
  with gr.Column():
 
581
  with gr.Column():
582
  interview_output = gr.Markdown()
583
 
 
584
  with gr.TabItem("🛠️ Builders"):
585
  gr.Markdown("### 🗄️ SQL")
586
  with gr.Row():
 
591
  with gr.Column():
592
  sql_output = gr.Code(lines=6)
593
 
594
+ gr.Markdown("### 🐚 Shell")
595
  with gr.Row():
596
  with gr.Column():
597
  shell_desc = gr.Textbox(label="Describe", lines=2)
 
600
  with gr.Column():
601
  shell_output = gr.Code(lines=6)
602
 
603
+ gr.Markdown("### ⏰ Cron")
604
  with gr.Row():
605
  with gr.Column():
606
  cron_desc = gr.Textbox(label="Describe", lines=2)
 
608
  with gr.Column():
609
  cron_output = gr.Markdown()
610
 
611
+ gr.Markdown("### 🎯 Regex")
612
  with gr.Row():
613
  with gr.Column():
614
  regex_desc = gr.Textbox(label="Describe", lines=2)
 
616
  with gr.Column():
617
  regex_output = gr.Markdown()
618
 
619
+ gr.Markdown("### 🔗 API")
620
  with gr.Row():
621
  with gr.Column():
622
  api_desc = gr.Textbox(label="Describe", lines=2)
 
625
  with gr.Column():
626
  api_output = gr.Code(lines=8)
627
 
 
628
  with gr.TabItem("📦 Data"):
629
  gr.Markdown("### 📦 Mock Data")
630
  with gr.Row():
 
637
  with gr.Column():
638
  mock_output = gr.Code(lines=10)
639
 
640
+ gr.Markdown("### 🔄 Format Converter")
641
  with gr.Row():
642
  with gr.Column():
643
  format_input = gr.Code(label="Input", lines=6)
 
648
  with gr.Column():
649
  format_output = gr.Code(label="Output", lines=6)
650
 
651
+ gr.HTML('<div style="text-align:center;padding:16px;opacity:0.6;">🔥 Axon v6 • <a href="https://huggingface.co/AIencoder">AIencoder</a> • <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels">Wheels</a></div>')
 
 
 
 
 
 
 
 
 
652
 
653
+ # Events
 
654
  def respond(message, history, model, temp, tokens):
 
655
  for updated in chat_stream(message, history, model, temp, tokens):
656
  yield updated, ""
657
 
658
  msg.submit(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
659
  send.click(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
660
  clear.click(lambda: [], None, chatbot)
661
+ transcribe_btn.click(transcribe_audio, audio, msg)
662
 
 
663
  def handle_chat_export(history):
664
  file, status = export_chat_history(history)
665
  return gr.update(value=file, visible=file is not None), status
 
671
  export_chat_btn.click(handle_chat_export, chatbot, [chat_export_file, chat_export_status])
672
  gen_export_btn.click(handle_code_export, [gen_output, gen_lang], [gen_export_file, gen_export_status])
673
 
674
+ gen_btn.click(generate_stream, [gen_prompt, gen_lang, model_dropdown, temperature, max_tokens], gen_output)
675
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
676
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
677
  review_btn.click(review_code, [review_input, model_dropdown, max_tokens], review_output)
 
679
  test_btn.click(generate_tests, [test_input, test_lang, test_fw, model_dropdown, max_tokens], test_output)
680
  doc_btn.click(document_code, [doc_input, doc_lang, doc_style, model_dropdown, max_tokens], doc_output)
681
  opt_btn.click(optimize_code, [opt_input, opt_lang, opt_focus, model_dropdown, max_tokens], opt_output)
 
682
  security_btn.click(security_scan, [security_input, model_dropdown, max_tokens], security_output)
683
  complexity_btn.click(analyze_complexity, [complexity_input, model_dropdown, max_tokens], complexity_output)
684
  diff_btn.click(code_diff, [diff_code1, diff_code2, model_dropdown, max_tokens], diff_output)
685
  pseudo_btn.click(to_pseudocode, [pseudo_input, pseudo_type, model_dropdown, max_tokens], pseudo_output)
686
  interview_btn.click(interview_challenge, [interview_topic, interview_diff, interview_lang, model_dropdown, max_tokens], interview_output)
 
687
  sql_btn.click(build_sql, [sql_desc, sql_type, model_dropdown, max_tokens], sql_output)
688
  shell_btn.click(build_shell, [shell_desc, shell_type, model_dropdown, max_tokens], shell_output)
689
  cron_btn.click(build_cron, [cron_desc, model_dropdown, max_tokens], cron_output)
690
  regex_btn.click(build_regex, [regex_desc, model_dropdown, max_tokens], regex_output)
691
  api_btn.click(build_api, [api_desc, api_fw, model_dropdown, max_tokens], api_output)
 
692
  mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
693
  format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
694
 
695
+ print("🔥 Axon v6 starting...")
 
 
 
 
696
  demo.launch(server_name="0.0.0.0", server_port=7860)