AIencoder commited on
Commit
6578d19
·
verified ·
1 Parent(s): bec0344

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +218 -58
app.py CHANGED
@@ -2,6 +2,7 @@ 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
@@ -49,7 +50,6 @@ def load_model(model_name):
49
  if model_name == current_model_name and model_name in loaded_models:
50
  return loaded_models[model_name]
51
 
52
- # Unload previous model to save RAM
53
  if current_model_name and current_model_name != model_name:
54
  if current_model_name in loaded_models:
55
  del loaded_models[current_model_name]
@@ -78,7 +78,7 @@ def load_model(model_name):
78
  print(f"✅ {model_name} loaded!")
79
  return llm
80
  except Exception as e:
81
- print(f"❌ Failed to load {model_name}: {e}")
82
  return None
83
 
84
  # ===== WHISPER =====
@@ -100,8 +100,8 @@ init_whisper()
100
  def get_status():
101
  available = [name for name, file in MODELS.items() if os.path.exists(os.path.join(MODELS_DIR, file))]
102
  if current_model_name:
103
- short_name = current_model_name.split()[1] if len(current_model_name.split()) > 1 else current_model_name
104
- return f"🟢 Ready • {len(available)} models • Active: {short_name}"
105
  return f"🟡 {len(available)} models available"
106
 
107
  def get_model_info(model_name):
@@ -131,11 +131,10 @@ def generate_response(model_name, prompt, temperature=0.7, max_tokens=2048):
131
  return "❌ **Model not available.**"
132
 
133
  try:
134
- # Different formats for different models
135
  if "deepseek" in model_name.lower():
136
  formatted = f"### Instruction:\n{prompt}\n\n### Response:\n"
137
  stop_tokens = ["### Instruction:", "### Response:"]
138
- else: # Qwen format
139
  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"
140
  stop_tokens = ["<|im_end|>", "<|im_start|>"]
141
 
@@ -154,6 +153,7 @@ def generate_response(model_name, prompt, temperature=0.7, max_tokens=2048):
154
  return response if response else "⚠️ Empty response."
155
  except Exception as e:
156
  return f"❌ **Error:** {str(e)[:100]}"
 
157
  def extract_code(text):
158
  if not text or "```" not in text:
159
  return text
@@ -168,6 +168,47 @@ def extract_code(text):
168
  pass
169
  return text
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  # ===== STREAMING =====
172
 
173
  def chat_stream(message, history, model_name, temperature, max_tokens):
@@ -181,25 +222,25 @@ def chat_stream(message, history, model_name, temperature, max_tokens):
181
  yield history + [[message, "❌ Model not available."]]
182
  return
183
 
184
- conv = "<|im_start|>system\nYou are an expert coding assistant. Use markdown code blocks.<|im_end|>\n"
185
- for u, a in history:
186
- conv += f"<|im_start|>user\n{u}<|im_end|>\n"
187
- if a:
188
- conv += f"<|im_start|>assistant\n{a}<|im_end|>\n"
189
- conv += f"<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
 
 
 
 
 
 
 
 
190
 
191
  try:
192
  full = ""
193
- for chunk in llm(
194
- conv,
195
- max_tokens=max_tokens,
196
- temperature=temperature,
197
- top_p=0.9,
198
- stop=["<|im_end|>", "<|im_start|>"],
199
- stream=True
200
- ):
201
- token = chunk["choices"][0]["text"]
202
- full += token
203
  yield history + [[message, full]]
204
  except Exception as e:
205
  yield history + [[message, f"❌ {str(e)[:50]}"]]
@@ -215,11 +256,16 @@ def generate_stream(prompt, language, model_name, temperature, max_tokens):
215
  yield "❌ Model not available."
216
  return
217
 
218
- 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"
 
 
 
 
 
219
 
220
  try:
221
  full = ""
222
- for chunk in llm(formatted, max_tokens=max_tokens, temperature=temperature, stop=["<|im_end|>"], stream=True):
223
  full += chunk["choices"][0]["text"]
224
  yield extract_code(full)
225
  except Exception as e:
@@ -281,8 +327,6 @@ def optimize_code(code, language, focus, model_name, max_tokens):
281
  return err
282
  return generate_response(model_name, f"Optimize {language} for {focus.lower()}. Explain:\n{code}", 0.3, max_tokens)
283
 
284
- # ===== NEW FEATURES =====
285
-
286
  def security_scan(code, model_name, max_tokens):
287
  valid, err = validate_input(code, "Code")
288
  if not valid:
@@ -408,36 +452,126 @@ def convert_data_format(data, from_fmt, to_fmt, model_name, max_tokens):
408
  result = generate_response(model_name, f"Convert {from_fmt} to {to_fmt}:\n{data}\n\nOutput only:", 0.1, max_tokens)
409
  return result if result.startswith("❌") else extract_code(result)
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  # ===== UI =====
412
 
413
- with gr.Blocks(title="Axon v6") as demo:
414
 
 
 
 
 
415
  gr.HTML("""
416
  <div style="background: linear-gradient(135deg, #6366f1, #8b5cf6, #06b6d4); border-radius: 16px; padding: 24px; margin-bottom: 16px;">
417
- <h1 style="color: white; margin: 0; font-size: 2rem;">🔥 Axon v6</h1>
418
- <p style="color: rgba(255,255,255,0.9); margin: 4px 0 0 0;">llama.cpp Edition • 19 Tools • Community Wheels! 🛞</p>
419
- <div style="display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap;">
420
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🤖 3 Models</span>
421
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🛠️ 19 Tools</span>
422
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">⚡ llama.cpp</span>
423
- <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🔒 Local</span>
 
 
 
424
  </div>
425
  </div>
426
  """)
427
 
428
- status = gr.Markdown(value=get_status, every=5)
 
 
429
 
 
430
  with gr.Row():
431
- model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
432
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
433
  max_tokens = gr.Slider(256, 4096, value=2048, step=256, label="📏 Max Tokens", scale=2)
434
 
435
- model_info = gr.Markdown(value="⚖️ Balanced • ~2GB • Recommended")
436
  model_dropdown.change(get_model_info, model_dropdown, model_info)
437
 
438
  with gr.Tabs():
439
 
440
- # Chat
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  with gr.TabItem("💬 Chat"):
442
  chatbot = gr.Chatbot(height=400)
443
  with gr.Row():
@@ -447,8 +581,12 @@ with gr.Blocks(title="Axon v6") as demo:
447
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
448
  transcribe = gr.Button("🎤 Transcribe", scale=1)
449
  clear = gr.Button("🗑️ Clear", scale=1)
 
 
 
 
450
 
451
- # Generate
452
  with gr.TabItem("⚡ Generate"):
453
  with gr.Row():
454
  with gr.Column():
@@ -459,8 +597,12 @@ with gr.Blocks(title="Axon v6") as demo:
459
  gen_btn = gr.Button("⚡ Generate", variant="primary")
460
  with gr.Column():
461
  gen_output = gr.Code(label="Code", language="python", lines=14)
 
 
 
 
462
 
463
- # Explain
464
  with gr.TabItem("🔍 Explain"):
465
  with gr.Row():
466
  with gr.Column():
@@ -470,7 +612,7 @@ with gr.Blocks(title="Axon v6") as demo:
470
  with gr.Column():
471
  explain_output = gr.Markdown()
472
 
473
- # Debug
474
  with gr.TabItem("🔧 Debug"):
475
  with gr.Row():
476
  with gr.Column():
@@ -480,7 +622,7 @@ with gr.Blocks(title="Axon v6") as demo:
480
  with gr.Column():
481
  fix_output = gr.Markdown()
482
 
483
- # Review
484
  with gr.TabItem("📋 Review"):
485
  with gr.Row():
486
  with gr.Column():
@@ -489,7 +631,7 @@ with gr.Blocks(title="Axon v6") as demo:
489
  with gr.Column():
490
  review_output = gr.Markdown()
491
 
492
- # Security
493
  with gr.TabItem("🔐 Security"):
494
  with gr.Row():
495
  with gr.Column():
@@ -498,7 +640,7 @@ with gr.Blocks(title="Axon v6") as demo:
498
  with gr.Column():
499
  security_output = gr.Markdown()
500
 
501
- # Complexity
502
  with gr.TabItem("📊 Complexity"):
503
  with gr.Row():
504
  with gr.Column():
@@ -507,7 +649,7 @@ with gr.Blocks(title="Axon v6") as demo:
507
  with gr.Column():
508
  complexity_output = gr.Markdown()
509
 
510
- # Convert
511
  with gr.TabItem("🔄 Convert"):
512
  with gr.Row():
513
  with gr.Column():
@@ -519,7 +661,7 @@ with gr.Blocks(title="Axon v6") as demo:
519
  with gr.Column():
520
  convert_output = gr.Code(label="Result", lines=10)
521
 
522
- # Test
523
  with gr.TabItem("🧪 Test"):
524
  with gr.Row():
525
  with gr.Column():
@@ -531,7 +673,7 @@ with gr.Blocks(title="Axon v6") as demo:
531
  with gr.Column():
532
  test_output = gr.Code(label="Tests", lines=10)
533
 
534
- # Document
535
  with gr.TabItem("📝 Document"):
536
  with gr.Row():
537
  with gr.Column():
@@ -543,7 +685,7 @@ with gr.Blocks(title="Axon v6") as demo:
543
  with gr.Column():
544
  doc_output = gr.Code(label="Documented", lines=10)
545
 
546
- # Optimize
547
  with gr.TabItem("🚀 Optimize"):
548
  with gr.Row():
549
  with gr.Column():
@@ -555,7 +697,7 @@ with gr.Blocks(title="Axon v6") as demo:
555
  with gr.Column():
556
  opt_output = gr.Markdown()
557
 
558
- # Diff
559
  with gr.TabItem("🔀 Diff"):
560
  with gr.Row():
561
  with gr.Column():
@@ -565,7 +707,7 @@ with gr.Blocks(title="Axon v6") as demo:
565
  with gr.Column():
566
  diff_output = gr.Markdown()
567
 
568
- # Pseudocode
569
  with gr.TabItem("📐 Pseudo"):
570
  with gr.Row():
571
  with gr.Column():
@@ -575,7 +717,7 @@ with gr.Blocks(title="Axon v6") as demo:
575
  with gr.Column():
576
  pseudo_output = gr.Markdown()
577
 
578
- # Interview
579
  with gr.TabItem("🎓 Interview"):
580
  with gr.Row():
581
  with gr.Column():
@@ -587,7 +729,7 @@ with gr.Blocks(title="Axon v6") as demo:
587
  with gr.Column():
588
  interview_output = gr.Markdown()
589
 
590
- # Builders
591
  with gr.TabItem("🛠️ Builders"):
592
  gr.Markdown("### 🗄️ SQL")
593
  with gr.Row():
@@ -632,7 +774,7 @@ with gr.Blocks(title="Axon v6") as demo:
632
  with gr.Column():
633
  api_output = gr.Code(lines=8)
634
 
635
- # Data
636
  with gr.TabItem("📦 Data"):
637
  gr.Markdown("### 📦 Mock Data")
638
  with gr.Row():
@@ -656,13 +798,19 @@ with gr.Blocks(title="Axon v6") as demo:
656
  with gr.Column():
657
  format_output = gr.Code(label="Output", lines=6)
658
 
 
659
  gr.HTML("""
660
- <div style="text-align:center;padding:16px;opacity:0.6;">
661
- 🔥 Axon v6 llama.cpp Wheels: <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank" style="color:#8b5cf6;">AIencoder/llama-cpp-wheels</a>
 
 
 
 
662
  </div>
663
  """)
664
 
665
  # ===== EVENTS =====
 
666
  def respond(message, history, model, temp, tokens):
667
  history = history or []
668
  for updated in chat_stream(message, history, model, temp, tokens):
@@ -673,6 +821,18 @@ with gr.Blocks(title="Axon v6") as demo:
673
  clear.click(lambda: [], None, chatbot)
674
  transcribe.click(transcribe_audio, audio, msg)
675
 
 
 
 
 
 
 
 
 
 
 
 
 
676
  gen_btn.click(generate_stream, [gen_prompt, gen_lang, model_dropdown, gen_temp, max_tokens], gen_output)
677
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
678
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
@@ -697,8 +857,8 @@ with gr.Blocks(title="Axon v6") as demo:
697
  mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
698
  format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
699
 
700
- # Preload default model
701
- print("🔥 Preloading default model...")
702
- load_model("Qwen2.5 Coder 3B (Fast)")
703
 
704
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  import json
3
  import time
4
  import os
5
+ from datetime import datetime
6
  from pathlib import Path
7
  from llama_cpp import Llama
8
  from faster_whisper import WhisperModel
 
50
  if model_name == current_model_name and model_name in loaded_models:
51
  return loaded_models[model_name]
52
 
 
53
  if current_model_name and current_model_name != model_name:
54
  if current_model_name in loaded_models:
55
  del loaded_models[current_model_name]
 
78
  print(f"✅ {model_name} loaded!")
79
  return llm
80
  except Exception as e:
81
+ print(f"❌ Failed to load: {e}")
82
  return None
83
 
84
  # ===== WHISPER =====
 
100
  def get_status():
101
  available = [name for name, file in MODELS.items() if os.path.exists(os.path.join(MODELS_DIR, file))]
102
  if current_model_name:
103
+ short = current_model_name.split('(')[0].strip().split()[-1]
104
+ return f"🟢 Ready • {len(available)} models • Active: {short}"
105
  return f"🟡 {len(available)} models available"
106
 
107
  def get_model_info(model_name):
 
131
  return "❌ **Model not available.**"
132
 
133
  try:
 
134
  if "deepseek" in model_name.lower():
135
  formatted = f"### Instruction:\n{prompt}\n\n### Response:\n"
136
  stop_tokens = ["### Instruction:", "### Response:"]
137
+ else:
138
  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"
139
  stop_tokens = ["<|im_end|>", "<|im_start|>"]
140
 
 
153
  return response if response else "⚠️ Empty response."
154
  except Exception as e:
155
  return f"❌ **Error:** {str(e)[:100]}"
156
+
157
  def extract_code(text):
158
  if not text or "```" not in text:
159
  return text
 
168
  pass
169
  return text
170
 
171
+ # ===== HISTORY FUNCTIONS =====
172
+
173
+ def export_chat_history(history):
174
+ if not history:
175
+ return None, "⚠️ No chat history to export."
176
+
177
+ export = {
178
+ "exported_at": datetime.now().isoformat(),
179
+ "tool": "Axon v6 Chat",
180
+ "messages": []
181
+ }
182
+
183
+ for user_msg, assistant_msg in history:
184
+ export["messages"].append({"role": "user", "content": user_msg})
185
+ export["messages"].append({"role": "assistant", "content": assistant_msg})
186
+
187
+ filename = f"/tmp/axon_chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
188
+ with open(filename, "w") as f:
189
+ json.dump(export, f, indent=2)
190
+
191
+ return filename, f"✅ Exported {len(history)} messages!"
192
+
193
+ def export_code(code, language):
194
+ if not code or not code.strip():
195
+ return None, "⚠️ No code to export."
196
+
197
+ ext_map = {
198
+ "Python": "py", "JavaScript": "js", "TypeScript": "ts", "Go": "go",
199
+ "Rust": "rs", "Java": "java", "C++": "cpp", "C#": "cs", "C": "c",
200
+ "PHP": "php", "Ruby": "rb", "Swift": "swift", "Kotlin": "kt",
201
+ "HTML/CSS": "html", "SQL": "sql", "Bash": "sh", "PowerShell": "ps1", "Lua": "lua"
202
+ }
203
+
204
+ ext = ext_map.get(language, "txt")
205
+ filename = f"/tmp/axon_code_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{ext}"
206
+
207
+ with open(filename, "w") as f:
208
+ f.write(code)
209
+
210
+ return filename, f"✅ Exported as .{ext}!"
211
+
212
  # ===== STREAMING =====
213
 
214
  def chat_stream(message, history, model_name, temperature, max_tokens):
 
222
  yield history + [[message, "❌ Model not available."]]
223
  return
224
 
225
+ if "deepseek" in model_name.lower():
226
+ conv = "### Instruction:\nYou are an expert coding assistant. Use markdown code blocks.\n\n"
227
+ for u, a in history:
228
+ conv += f"User: {u}\nAssistant: {a}\n\n"
229
+ conv += f"User: {message}\n\n### Response:\n"
230
+ stop_tokens = ["### Instruction:", "User:"]
231
+ else:
232
+ conv = "<|im_start|>system\nYou are an expert coding assistant. Use markdown code blocks.<|im_end|>\n"
233
+ for u, a in history:
234
+ conv += f"<|im_start|>user\n{u}<|im_end|>\n"
235
+ if a:
236
+ conv += f"<|im_start|>assistant\n{a}<|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
 
240
  try:
241
  full = ""
242
+ for chunk in llm(conv, max_tokens=max_tokens, temperature=temperature, top_p=0.9, stop=stop_tokens, stream=True):
243
+ full += chunk["choices"][0]["text"]
 
 
 
 
 
 
 
 
244
  yield history + [[message, full]]
245
  except Exception as e:
246
  yield history + [[message, f"❌ {str(e)[:50]}"]]
 
256
  yield "❌ Model not available."
257
  return
258
 
259
+ if "deepseek" in model_name.lower():
260
+ formatted = f"### Instruction:\nWrite clean {language} code with comments:\n{prompt}\n\nOutput only code:\n\n### Response:\n"
261
+ stop_tokens = ["### Instruction:"]
262
+ else:
263
+ 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"
264
+ stop_tokens = ["<|im_end|>"]
265
 
266
  try:
267
  full = ""
268
+ for chunk in llm(formatted, max_tokens=max_tokens, temperature=temperature, stop=stop_tokens, stream=True):
269
  full += chunk["choices"][0]["text"]
270
  yield extract_code(full)
271
  except Exception as e:
 
327
  return err
328
  return generate_response(model_name, f"Optimize {language} for {focus.lower()}. Explain:\n{code}", 0.3, max_tokens)
329
 
 
 
330
  def security_scan(code, model_name, max_tokens):
331
  valid, err = validate_input(code, "Code")
332
  if not valid:
 
452
  result = generate_response(model_name, f"Convert {from_fmt} to {to_fmt}:\n{data}\n\nOutput only:", 0.1, max_tokens)
453
  return result if result.startswith("❌") else extract_code(result)
454
 
455
+ # ===== THEME =====
456
+
457
+ light_theme = gr.themes.Soft(
458
+ primary_hue="indigo",
459
+ secondary_hue="blue",
460
+ )
461
+
462
+ dark_theme = gr.themes.Soft(
463
+ primary_hue="indigo",
464
+ secondary_hue="blue",
465
+ ).set(
466
+ body_background_fill="#0f172a",
467
+ body_background_fill_dark="#0f172a",
468
+ block_background_fill="#1e293b",
469
+ block_background_fill_dark="#1e293b",
470
+ border_color_primary="#334155",
471
+ border_color_primary_dark="#334155",
472
+ )
473
+
474
  # ===== UI =====
475
 
476
+ with gr.Blocks(title="Axon v6", theme=dark_theme) as demo:
477
 
478
+ # State for theme
479
+ is_dark = gr.State(True)
480
+
481
+ # Header
482
  gr.HTML("""
483
  <div style="background: linear-gradient(135deg, #6366f1, #8b5cf6, #06b6d4); border-radius: 16px; padding: 24px; margin-bottom: 16px;">
484
+ <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;">
485
+ <div>
486
+ <h1 style="color: white; margin: 0; font-size: 2rem;">🔥 Axon v6</h1>
487
+ <p style="color: rgba(255,255,255,0.9); margin: 4px 0 0 0;">AI Coding Assistant 8 Models • 19 Tools • 100% Local</p>
488
+ </div>
489
+ <div style="display: flex; gap: 8px; flex-wrap: wrap;">
490
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🤖 8 Models</span>
491
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">🛠️ 19 Tools</span>
492
+ <span style="background: rgba(255,255,255,0.2); padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; color: white;">⚡ llama.cpp</span>
493
+ </div>
494
  </div>
495
  </div>
496
  """)
497
 
498
+ # Status row
499
+ with gr.Row():
500
+ status = gr.Markdown(value=get_status, every=5)
501
 
502
+ # Settings
503
  with gr.Row():
504
+ model_dropdown = gr.Dropdown(choices=list(MODELS.keys()), value="🚀 Qwen2.5 Coder 3B (Fast)", label="🤖 Model", scale=3)
505
  temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="🌡️ Creativity", scale=2)
506
  max_tokens = gr.Slider(256, 4096, value=2048, step=256, label="📏 Max Tokens", scale=2)
507
 
508
+ model_info = gr.Markdown(value="🚀 Fast • ~2GB • Great all-rounder")
509
  model_dropdown.change(get_model_info, model_dropdown, model_info)
510
 
511
  with gr.Tabs():
512
 
513
+ # ===== HOME =====
514
+ with gr.TabItem("🏠 Home"):
515
+ gr.HTML("""
516
+ <div style="padding: 20px;">
517
+ <h2 style="margin-top: 0;">Welcome to Axon v6! 🔥</h2>
518
+ <p>The ultimate free AI coding assistant - running 100% locally on your browser.</p>
519
+
520
+ <h3>🚀 Quick Start</h3>
521
+ <ol>
522
+ <li><strong>Select a model</strong> from the dropdown above</li>
523
+ <li><strong>Choose a tool</strong> from the tabs</li>
524
+ <li><strong>Start coding!</strong></li>
525
+ </ol>
526
+
527
+ <h3>🤖 Models</h3>
528
+ <table style="width: 100%; border-collapse: collapse;">
529
+ <tr style="background: rgba(99, 102, 241, 0.2);">
530
+ <th style="padding: 8px; text-align: left;">Model</th>
531
+ <th style="padding: 8px; text-align: left;">Size</th>
532
+ <th style="padding: 8px; text-align: left;">Best For</th>
533
+ </tr>
534
+ <tr><td style="padding: 8px;">⭐ Qwen3 30B-A3B</td><td>~10GB</td><td>Best quality (MoE)</td></tr>
535
+ <tr><td style="padding: 8px;">🏆 Qwen2.5 14B</td><td>~8GB</td><td>Premium tasks</td></tr>
536
+ <tr><td style="padding: 8px;">🧠 DeepSeek V2 Lite</td><td>~9GB</td><td>Complex logic</td></tr>
537
+ <tr><td style="padding: 8px;">⚖️ Qwen2.5 7B</td><td>~4.5GB</td><td>Balanced</td></tr>
538
+ <tr><td style="padding: 8px;">🚀 Qwen2.5 3B</td><td>~2GB</td><td>Fast & capable</td></tr>
539
+ <tr><td style="padding: 8px;">⚡ DeepSeek 6.7B</td><td>~4GB</td><td>Algorithms</td></tr>
540
+ <tr><td style="padding: 8px;">💨 Qwen2.5 1.5B</td><td>~1GB</td><td>Quick tasks</td></tr>
541
+ <tr><td style="padding: 8px;">🔬 Qwen2.5 0.5B</td><td>~0.3GB</td><td>Instant</td></tr>
542
+ </table>
543
+
544
+ <h3>🛠️ 19 Tools Available</h3>
545
+ <p>
546
+ <strong>Core:</strong> Chat, Generate, Explain, Debug, Review<br>
547
+ <strong>Advanced:</strong> Security, Complexity, Convert, Test, Document, Optimize, Diff, Pseudo, Interview<br>
548
+ <strong>Builders:</strong> SQL, Shell, Cron, Regex, API<br>
549
+ <strong>Data:</strong> Mock Data, Format Converter
550
+ </p>
551
+
552
+ <h3>🔗 Links</h3>
553
+ <p>
554
+ <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank">🛞 Pre-built Wheels</a> •
555
+ <a href="https://github.com/ggerganov/llama.cpp" target="_blank">📦 llama.cpp</a> •
556
+ <a href="https://huggingface.co/Qwen" target="_blank">🤖 Qwen Models</a>
557
+ </p>
558
+ </div>
559
+ """)
560
+
561
+ # Share buttons
562
+ gr.HTML("""
563
+ <div style="padding: 20px; border-top: 1px solid #334155;">
564
+ <h3>📤 Share Axon</h3>
565
+ <div style="display: flex; gap: 10px; flex-wrap: wrap;">
566
+ <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>
567
+ <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>
568
+ <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>
569
+ <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>
570
+ </div>
571
+ </div>
572
+ """)
573
+
574
+ # ===== CHAT =====
575
  with gr.TabItem("💬 Chat"):
576
  chatbot = gr.Chatbot(height=400)
577
  with gr.Row():
 
581
  audio = gr.Audio(sources=["microphone"], type="filepath", label="🎤", scale=2)
582
  transcribe = gr.Button("🎤 Transcribe", scale=1)
583
  clear = gr.Button("🗑️ Clear", scale=1)
584
+ export_chat_btn = gr.Button("💾 Export", scale=1)
585
+
586
+ chat_export_file = gr.File(label="Download", visible=False)
587
+ chat_export_status = gr.Markdown("")
588
 
589
+ # ===== GENERATE =====
590
  with gr.TabItem("⚡ Generate"):
591
  with gr.Row():
592
  with gr.Column():
 
597
  gen_btn = gr.Button("⚡ Generate", variant="primary")
598
  with gr.Column():
599
  gen_output = gr.Code(label="Code", language="python", lines=14)
600
+ with gr.Row():
601
+ gen_export_btn = gr.Button("💾 Export Code")
602
+ gen_export_status = gr.Markdown("")
603
+ gen_export_file = gr.File(label="Download", visible=False)
604
 
605
+ # ===== EXPLAIN =====
606
  with gr.TabItem("🔍 Explain"):
607
  with gr.Row():
608
  with gr.Column():
 
612
  with gr.Column():
613
  explain_output = gr.Markdown()
614
 
615
+ # ===== DEBUG =====
616
  with gr.TabItem("🔧 Debug"):
617
  with gr.Row():
618
  with gr.Column():
 
622
  with gr.Column():
623
  fix_output = gr.Markdown()
624
 
625
+ # ===== REVIEW =====
626
  with gr.TabItem("📋 Review"):
627
  with gr.Row():
628
  with gr.Column():
 
631
  with gr.Column():
632
  review_output = gr.Markdown()
633
 
634
+ # ===== SECURITY =====
635
  with gr.TabItem("🔐 Security"):
636
  with gr.Row():
637
  with gr.Column():
 
640
  with gr.Column():
641
  security_output = gr.Markdown()
642
 
643
+ # ===== COMPLEXITY =====
644
  with gr.TabItem("📊 Complexity"):
645
  with gr.Row():
646
  with gr.Column():
 
649
  with gr.Column():
650
  complexity_output = gr.Markdown()
651
 
652
+ # ===== CONVERT =====
653
  with gr.TabItem("🔄 Convert"):
654
  with gr.Row():
655
  with gr.Column():
 
661
  with gr.Column():
662
  convert_output = gr.Code(label="Result", lines=10)
663
 
664
+ # ===== TEST =====
665
  with gr.TabItem("🧪 Test"):
666
  with gr.Row():
667
  with gr.Column():
 
673
  with gr.Column():
674
  test_output = gr.Code(label="Tests", lines=10)
675
 
676
+ # ===== DOCUMENT =====
677
  with gr.TabItem("📝 Document"):
678
  with gr.Row():
679
  with gr.Column():
 
685
  with gr.Column():
686
  doc_output = gr.Code(label="Documented", lines=10)
687
 
688
+ # ===== OPTIMIZE =====
689
  with gr.TabItem("🚀 Optimize"):
690
  with gr.Row():
691
  with gr.Column():
 
697
  with gr.Column():
698
  opt_output = gr.Markdown()
699
 
700
+ # ===== DIFF =====
701
  with gr.TabItem("🔀 Diff"):
702
  with gr.Row():
703
  with gr.Column():
 
707
  with gr.Column():
708
  diff_output = gr.Markdown()
709
 
710
+ # ===== PSEUDOCODE =====
711
  with gr.TabItem("📐 Pseudo"):
712
  with gr.Row():
713
  with gr.Column():
 
717
  with gr.Column():
718
  pseudo_output = gr.Markdown()
719
 
720
+ # ===== INTERVIEW =====
721
  with gr.TabItem("🎓 Interview"):
722
  with gr.Row():
723
  with gr.Column():
 
729
  with gr.Column():
730
  interview_output = gr.Markdown()
731
 
732
+ # ===== BUILDERS =====
733
  with gr.TabItem("🛠️ Builders"):
734
  gr.Markdown("### 🗄️ SQL")
735
  with gr.Row():
 
774
  with gr.Column():
775
  api_output = gr.Code(lines=8)
776
 
777
+ # ===== DATA =====
778
  with gr.TabItem("📦 Data"):
779
  gr.Markdown("### 📦 Mock Data")
780
  with gr.Row():
 
798
  with gr.Column():
799
  format_output = gr.Code(label="Output", lines=6)
800
 
801
+ # Footer
802
  gr.HTML("""
803
+ <div style="text-align:center;padding:16px;border-top:1px solid #334155;margin-top:20px;">
804
+ <p style="opacity:0.7;">🔥 Axon v6 • Built with ❤️ by <a href="https://huggingface.co/AIencoder" target="_blank" style="color:#8b5cf6;">AIencoder</a></p>
805
+ <p style="opacity:0.5;font-size:0.8rem;">
806
+ Wheels: <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank" style="color:#8b5cf6;">AIencoder/llama-cpp-wheels</a> •
807
+ Powered by <a href="https://github.com/ggerganov/llama.cpp" target="_blank" style="color:#8b5cf6;">llama.cpp</a>
808
+ </p>
809
  </div>
810
  """)
811
 
812
  # ===== EVENTS =====
813
+
814
  def respond(message, history, model, temp, tokens):
815
  history = history or []
816
  for updated in chat_stream(message, history, model, temp, tokens):
 
821
  clear.click(lambda: [], None, chatbot)
822
  transcribe.click(transcribe_audio, audio, msg)
823
 
824
+ # Export handlers
825
+ def handle_chat_export(history):
826
+ file, status = export_chat_history(history)
827
+ return gr.update(value=file, visible=file is not None), status
828
+
829
+ def handle_code_export(code, lang):
830
+ file, status = export_code(code, lang)
831
+ return gr.update(value=file, visible=file is not None), status
832
+
833
+ export_chat_btn.click(handle_chat_export, chatbot, [chat_export_file, chat_export_status])
834
+ gen_export_btn.click(handle_code_export, [gen_output, gen_lang], [gen_export_file, gen_export_status])
835
+
836
  gen_btn.click(generate_stream, [gen_prompt, gen_lang, model_dropdown, gen_temp, max_tokens], gen_output)
837
  explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
838
  fix_btn.click(fix_code, [fix_input, fix_error, model_dropdown, max_tokens], fix_output)
 
857
  mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
858
  format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
859
 
860
+ # Preload
861
+ print("🔥 Preloading model...")
862
+ load_model("🚀 Qwen2.5 Coder 3B (Fast)")
863
 
864
  demo.launch(server_name="0.0.0.0", server_port=7860)