AIencoder commited on
Commit
f9463d1
·
verified ·
1 Parent(s): d17c108

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +686 -608
app.py CHANGED
@@ -8,42 +8,72 @@ 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", # Fixed filename
 
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", # Fixed filename
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 • ~9GB • Best 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
- }
37
-
38
  LANGUAGES = [
39
- "Python", "JavaScript", "TypeScript", "Go", "Rust",
40
- "Java", "C++", "C#", "C", "PHP", "Ruby", "Swift", "Kotlin",
41
- "Scala", "R", "Julia", "Perl", "HTML/CSS", "SQL", "Bash", "PowerShell", "Lua"
42
  ]
43
 
44
- # ===== MODEL CACHE =====
45
  loaded_models = {}
46
  current_model_name = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  def load_model(model_name):
49
  global loaded_models, current_model_name
@@ -51,6 +81,7 @@ def load_model(model_name):
51
  if model_name == current_model_name and model_name in loaded_models:
52
  return loaded_models[model_name]
53
 
 
54
  if current_model_name and current_model_name != model_name:
55
  if current_model_name in loaded_models:
56
  del loaded_models[current_model_name]
@@ -60,21 +91,10 @@ def load_model(model_name):
60
  if not filename:
61
  return None
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}...")
80
  try:
@@ -93,642 +113,700 @@ def load_model(model_name):
93
  print(f"❌ Failed to load: {e}")
94
  return None
95
 
96
- # ===== WHISPER =====
97
- whisper_model = None
98
-
99
  def init_whisper():
100
  global whisper_model
101
  try:
102
- print("Loading Whisper...")
103
  whisper_model = WhisperModel("tiny", device="cpu", compute_type="int8")
104
  print("✅ Whisper ready!")
105
  except Exception as e:
106
  print(f"❌ Whisper failed: {e}")
107
 
108
- init_whisper()
109
-
110
- # ===== HELPERS =====
111
-
112
- def get_status():
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, "")
121
-
122
- def validate_input(text, name="Input"):
123
- if not text or not text.strip():
124
- return False, f"⚠️ {name} cannot be empty."
125
- if len(text) > 50000:
126
- return False, f"⚠️ {name} too long."
127
- return True, None
128
-
129
- def transcribe_audio(audio):
130
- if not audio:
131
- return ""
132
- if not whisper_model:
133
- return "❌ Whisper unavailable."
134
  try:
135
- segments, _ = whisper_model.transcribe(audio)
136
- return " ".join([s.text for s in segments]).strip() or "⚠️ No speech detected."
 
 
 
 
 
 
137
  except Exception as e:
138
- return f"❌ {str(e)[:50]}"
139
 
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():
147
- formatted = f"### Instruction:\n{prompt}\n\n### Response:\n"
148
- stop_tokens = ["### Instruction:", "### Response:"]
149
- else:
150
- 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"
151
- stop_tokens = ["<|im_end|>", "<|im_start|>"]
152
-
153
- output = llm(
154
- formatted,
155
  max_tokens=max_tokens,
156
  temperature=temperature,
157
- top_p=0.9,
158
- top_k=40,
159
- repeat_penalty=1.1,
160
- stop=stop_tokens,
161
  echo=False
162
  )
163
-
164
- response = output["choices"][0]["text"].strip()
165
- return response if response else "⚠️ Empty response."
 
 
166
  except Exception as e:
167
- return f"❌ **Error:** {str(e)[:100]}"
168
 
169
- def extract_code(text):
170
- if not text or "```" not in text:
171
- return text
 
 
 
 
172
  try:
173
- parts = text.split("```")
174
- if len(parts) >= 2:
175
- code = parts[1]
176
- if "\n" in code:
177
- code = code.split("\n", 1)[-1]
178
- return code.strip()
179
- except:
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
 
195
- def export_code(code, language):
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
 
203
- with open(filename, "w") as f:
204
- f.write(code)
 
 
 
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 []
 
212
 
213
- valid, error = validate_input(message, "Message")
214
- if not valid:
215
- history.append({"role": "user", "content": message})
216
- history.append({"role": "assistant", "content": error})
217
- yield history
218
- return
 
219
 
220
- llm = load_model(model_name)
221
- if not llm:
222
- history.append({"role": "user", "content": message})
223
- history.append({"role": "assistant", "content": "❌ Model not available."})
224
- yield history
225
- return
 
226
 
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
 
240
- history.append({"role": "user", "content": message})
241
- history.append({"role": "assistant", "content": ""})
 
 
 
 
242
 
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:
250
- history[-1]['content'] = f"❌ Error: {str(e)[:100]}"
251
- yield history
252
 
253
- def generate_stream(prompt, language, model_name, temperature, max_tokens):
254
- valid, error = validate_input(prompt, "Description")
255
- if not valid:
256
- yield error
257
- return
258
 
259
- llm = load_model(model_name)
260
- if not llm:
261
- yield "❌ Model not available."
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:
272
- full = ""
273
- for chunk in llm(formatted, max_tokens=max_tokens, temperature=temperature, stop=stop_tokens, stream=True):
274
- full += chunk["choices"][0]["text"]
275
- yield extract_code(full)
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") 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)
411
- max_tokens = gr.Slider(256, 4096, value=2048, step=256, label="📏 Max Tokens", scale=2)
 
 
 
 
412
 
413
- model_info = gr.Markdown(value="🚀 Fast ~2GB Great all-rounder")
414
- model_dropdown.change(get_model_info, model_dropdown, model_info)
 
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)
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():
481
- fix_input = gr.Code(label="Code", lines=8)
482
- fix_error = gr.Textbox(label="Error", lines=2)
483
- fix_btn = gr.Button("🔧 Fix", variant="primary")
484
- with gr.Column():
485
- fix_output = gr.Markdown()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
 
487
- with gr.TabItem("📋 Review"):
488
- with gr.Row():
489
- with gr.Column():
490
- review_input = gr.Code(label="Code", lines=10)
491
- review_btn = gr.Button("📋 Review", variant="primary")
492
- with gr.Column():
493
- review_output = gr.Markdown()
 
494
 
495
- with gr.TabItem("🔐 Security"):
496
- with gr.Row():
497
- with gr.Column():
498
- security_input = gr.Code(label="Code", lines=10)
499
- security_btn = gr.Button("🔐 Scan", variant="primary")
500
- with gr.Column():
501
- security_output = gr.Markdown()
 
 
502
 
503
- with gr.TabItem("📊 Complexity"):
504
- with gr.Row():
505
- with gr.Column():
506
- complexity_input = gr.Code(label="Code", lines=10)
507
- complexity_btn = gr.Button("📊 Analyze", variant="primary")
508
- with gr.Column():
509
- complexity_output = gr.Markdown()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
 
511
- with gr.TabItem("🔄 Convert"):
512
- with gr.Row():
513
- with gr.Column():
514
- convert_input = gr.Code(label="Source", lines=10)
515
- with gr.Row():
516
- convert_from = gr.Dropdown(LANGUAGES, value="Python", label="From")
517
- convert_to = gr.Dropdown(LANGUAGES, value="JavaScript", label="To")
518
- convert_btn = gr.Button("🔄 Convert", variant="primary")
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():
525
- test_input = gr.Code(label="Code", lines=10)
526
- with gr.Row():
527
- test_lang = gr.Dropdown(LANGUAGES[:10], value="Python", label="Language")
528
- test_fw = gr.Textbox(label="Framework", placeholder="pytest")
529
- test_btn = gr.Button("🧪 Generate", variant="primary")
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():
536
- doc_input = gr.Code(label="Code", lines=10)
537
- with gr.Row():
538
- doc_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
539
- doc_style = gr.Dropdown(["Docstrings", "Comments", "Both", "README"], value="Both")
540
- doc_btn = gr.Button("📝 Document", variant="primary")
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():
547
- opt_input = gr.Code(label="Code", lines=10)
548
- with gr.Row():
549
- opt_lang = gr.Dropdown(LANGUAGES, value="Python", label="Language")
550
- opt_focus = gr.Dropdown(["All", "Performance", "Readability", "Memory"], value="All")
551
- opt_btn = gr.Button("🚀 Optimize", variant="primary")
552
- with gr.Column():
553
- opt_output = gr.Markdown()
554
 
555
- with gr.TabItem("🔀 Diff"):
556
- with gr.Row():
557
- with gr.Column():
558
- diff_code1 = gr.Code(label="Code 1", lines=8)
559
- diff_code2 = gr.Code(label="Code 2", lines=8)
560
- diff_btn = gr.Button("🔀 Compare", variant="primary")
561
- with gr.Column():
562
- diff_output = gr.Markdown()
563
 
564
- with gr.TabItem("📐 Pseudo"):
565
- with gr.Row():
566
- with gr.Column():
567
- pseudo_input = gr.Code(label="Code", lines=10)
568
- pseudo_type = gr.Radio(["Pseudocode", "Flowchart"], value="Pseudocode")
569
- pseudo_btn = gr.Button("📐 Convert", variant="primary")
570
- with gr.Column():
571
- pseudo_output = gr.Markdown()
 
 
572
 
573
- with gr.TabItem("🎓 Interview"):
574
- with gr.Row():
575
- with gr.Column():
576
- interview_topic = gr.Textbox(label="Topic", placeholder="Binary trees...")
577
- with gr.Row():
578
- interview_diff = gr.Dropdown(["Easy", "Medium", "Hard"], value="Medium")
579
- interview_lang = gr.Dropdown(LANGUAGES[:8], value="Python")
580
- interview_btn = gr.Button("🎓 Generate", variant="primary")
581
- with gr.Column():
582
- interview_output = gr.Markdown()
583
 
584
- with gr.TabItem("🛠️ Builders"):
585
- gr.Markdown("### 🗄️ SQL")
586
- with gr.Row():
587
- with gr.Column():
588
- sql_desc = gr.Textbox(label="Describe", lines=2)
589
- sql_type = gr.Dropdown(["PostgreSQL", "MySQL", "SQLite"], value="PostgreSQL")
590
- sql_btn = gr.Button("🗄️ Build", variant="primary")
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)
598
- shell_type = gr.Dropdown(["Bash", "PowerShell", "Zsh"], value="Bash")
599
- shell_btn = gr.Button("🐚 Build", variant="primary")
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)
607
- cron_btn = gr.Button("⏰ Build", variant="primary")
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)
615
- regex_btn = gr.Button("🎯 Build", variant="primary")
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)
623
- api_fw = gr.Dropdown(["FastAPI", "Express", "Flask"], value="FastAPI")
624
- api_btn = gr.Button("🔗 Build", variant="primary")
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():
631
- with gr.Column():
632
- mock_schema = gr.Textbox(label="Schema", lines=2, placeholder="User: name, email, age...")
633
- with gr.Row():
634
- mock_count = gr.Slider(1, 20, value=5, step=1, label="Count")
635
- mock_format = gr.Dropdown(["JSON", "CSV", "SQL"], value="JSON")
636
- mock_btn = gr.Button("📦 Generate", variant="primary")
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)
644
- with gr.Row():
645
- format_from = gr.Dropdown(["JSON", "YAML", "XML", "CSV"], value="JSON")
646
- format_to = gr.Dropdown(["JSON", "YAML", "XML", "CSV"], value="YAML")
647
- format_btn = gr.Button("🔄 Convert", variant="primary")
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
666
-
667
- def handle_code_export(code, lang):
668
- file, status = export_code(code, lang)
669
- return gr.update(value=file, visible=file is not None), status
670
-
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)
678
- convert_btn.click(convert_code, [convert_input, convert_from, convert_to, model_dropdown, max_tokens], convert_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
- # Pre-download ALL models on startup
696
- print("🔥 Axon v6 starting...")
697
- print("⬇️ Pre-downloading all models...")
698
-
699
- download_results = {}
700
-
701
- for model_name, filename in MODELS.items():
702
- print(f"\n📥 Checking: {model_name}")
703
- print(f" Filename: {filename}")
704
- model_path = os.path.join(MODELS_DIR, filename)
705
 
706
- if os.path.exists(model_path):
707
- print(f" ✅ Already cached")
708
- download_results[model_name] = "cached"
709
- else:
710
- repo_id = MODEL_REPOS.get(filename)
711
- print(f" Repo: {repo_id}")
712
-
713
- if repo_id:
714
- try:
715
- print(f" ⬇️ Downloading...")
716
- hf_hub_download(repo_id=repo_id, filename=filename, local_dir=MODELS_DIR)
717
- print(f" Downloaded!")
718
- download_results[model_name] = "downloaded"
719
- except Exception as e:
720
- print(f" ❌ FAILED: {e}")
721
- download_results[model_name] = f"failed: {e}"
722
- else:
723
- print(f" No repo configured!")
724
- download_results[model_name] = "no repo"
725
-
726
- print("\n" + "="*50)
727
- print("📊 DOWNLOAD SUMMARY:")
728
- for model, status in download_results.items():
729
- emoji = "✅" if status in ["cached", "downloaded"] else "❌"
730
- print(f" {emoji} {model}: {status}")
731
- print("="*50 + "\n")
732
-
733
- print("🚀 Launching Axon...")
734
- demo.launch(server_name="0.0.0.0", server_port=7860, theme=gr.themes.Soft(primary_hue="indigo"))
 
8
  from huggingface_hub import hf_hub_download
9
 
10
  # ===== CONFIG =====
11
+ MODELS_DIR = "/data/models"
12
+ MAX_TOKENS = 2048
13
  CONTEXT_SIZE = 4096
14
 
15
+ # Model repos for auto-download (5 models to stay under 50GB)
16
  MODEL_REPOS = {
17
+ "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf": "bartowski/DeepSeek-Coder-V2-Lite-Instruct-GGUF",
18
+ "qwen2.5-coder-7b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-7B-Instruct-GGUF",
19
  "qwen2.5-coder-3b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-3B-Instruct-GGUF",
20
  "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF",
21
  "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf": "Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF",
 
22
  }
23
 
24
  MODELS = {
25
  "🧠 DeepSeek V2 Lite (Best)": "DeepSeek-Coder-V2-Lite-Instruct-Q4_K_M.gguf",
26
+ "⚖️ Qwen2.5 Coder 7B (Balanced)": "qwen2.5-coder-7b-instruct-q4_k_m.gguf",
27
  "🚀 Qwen2.5 Coder 3B (Fast)": "qwen2.5-coder-3b-instruct-q4_k_m.gguf",
28
  "💨 Qwen2.5 Coder 1.5B (Quick)": "qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",
29
  "🔬 Qwen2.5 Coder 0.5B (Instant)": "qwen2.5-coder-0.5b-instruct-q4_k_m.gguf",
30
  }
31
 
 
 
 
 
 
 
 
 
32
  LANGUAGES = [
33
+ "Python", "JavaScript", "TypeScript", "Go", "Rust", "Java", "C++", "C#", "C",
34
+ "PHP", "Ruby", "Swift", "Kotlin", "Scala", "R", "Julia", "Perl", "HTML/CSS",
35
+ "SQL", "Bash", "PowerShell", "Lua"
36
  ]
37
 
38
+ # ===== GLOBAL STATE =====
39
  loaded_models = {}
40
  current_model_name = None
41
+ whisper_model = None
42
+
43
+ # ===== INITIALIZATION =====
44
+ def init_directories():
45
+ os.makedirs(MODELS_DIR, exist_ok=True)
46
+ print(f"📁 Models directory: {MODELS_DIR}")
47
+
48
+ def get_cached_models():
49
+ if not os.path.exists(MODELS_DIR):
50
+ return []
51
+ return [f for f in os.listdir(MODELS_DIR) if f.endswith('.gguf')]
52
+
53
+ def download_model(filename):
54
+ """Download a model if not cached"""
55
+ model_path = os.path.join(MODELS_DIR, filename)
56
+ if os.path.exists(model_path):
57
+ return model_path
58
+
59
+ repo = MODEL_REPOS.get(filename)
60
+ if not repo:
61
+ print(f"❌ No repo found for {filename}")
62
+ return None
63
+
64
+ print(f"⬇️ Downloading {filename}...")
65
+ try:
66
+ path = hf_hub_download(
67
+ repo_id=repo,
68
+ filename=filename,
69
+ local_dir=MODELS_DIR,
70
+ local_dir_use_symlinks=False
71
+ )
72
+ print(f"✅ Downloaded {filename}")
73
+ return path
74
+ except Exception as e:
75
+ print(f"❌ Download failed: {e}")
76
+ return None
77
 
78
  def load_model(model_name):
79
  global loaded_models, current_model_name
 
81
  if model_name == current_model_name and model_name in loaded_models:
82
  return loaded_models[model_name]
83
 
84
+ # Unload previous model to save RAM
85
  if current_model_name and current_model_name != model_name:
86
  if current_model_name in loaded_models:
87
  del loaded_models[current_model_name]
 
91
  if not filename:
92
  return None
93
 
94
+ # Download if needed
95
+ model_path = download_model(filename)
96
+ if not model_path or not os.path.exists(model_path):
97
+ return None
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  print(f"📥 Loading {model_name}...")
100
  try:
 
113
  print(f"❌ Failed to load: {e}")
114
  return None
115
 
 
 
 
116
  def init_whisper():
117
  global whisper_model
118
  try:
119
+ print("🎤 Loading Whisper...")
120
  whisper_model = WhisperModel("tiny", device="cpu", compute_type="int8")
121
  print("✅ Whisper ready!")
122
  except Exception as e:
123
  print(f"❌ Whisper failed: {e}")
124
 
125
+ # ===== LLM HELPERS =====
126
+ def generate_response(prompt, model_name, max_tokens=MAX_TOKENS, temperature=0.7):
127
+ llm = load_model(model_name)
128
+ if not llm:
129
+ return "❌ Failed to load model. Please try again."
130
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  try:
132
+ response = llm(
133
+ prompt,
134
+ max_tokens=max_tokens,
135
+ temperature=temperature,
136
+ stop=["<|endoftext|>", "<|im_end|>", "</s>"],
137
+ echo=False
138
+ )
139
+ return response["choices"][0]["text"].strip()
140
  except Exception as e:
141
+ return f"❌ Error: {str(e)}"
142
 
143
+ def generate_stream(prompt, model_name, max_tokens=MAX_TOKENS, temperature=0.7):
144
  llm = load_model(model_name)
145
  if not llm:
146
+ yield "❌ Failed to load model. Please try again."
147
+ return
148
 
149
  try:
150
+ stream = llm(
151
+ prompt,
 
 
 
 
 
 
 
152
  max_tokens=max_tokens,
153
  temperature=temperature,
154
+ stop=["<|endoftext|>", "<|im_end|>", "</s>"],
155
+ stream=True,
 
 
156
  echo=False
157
  )
158
+ for chunk in stream:
159
+ if "choices" in chunk and chunk["choices"]:
160
+ text = chunk["choices"][0].get("text", "")
161
+ if text:
162
+ yield text
163
  except Exception as e:
164
+ yield f"❌ Error: {str(e)}"
165
 
166
+ def format_prompt(system, user):
167
+ return f"<|im_start|>system\n{system}<|im_end|>\n<|im_start|>user\n{user}<|im_end|>\n<|im_start|>assistant\n"
168
+
169
+ # ===== WHISPER =====
170
+ def transcribe_audio(audio_path):
171
+ if not whisper_model or not audio_path:
172
+ return ""
173
  try:
174
+ segments, _ = whisper_model.transcribe(audio_path, beam_size=1)
175
+ return " ".join([s.text for s in segments]).strip()
176
+ except Exception as e:
177
+ return f" Transcription error: {str(e)}"
 
 
 
 
 
178
 
179
+ # ===== TOOL FUNCTIONS =====
180
 
181
+ # --- CORE TOOLS ---
182
+ def chat_stream(message, history, model, temperature, max_tokens):
183
+ if not message.strip():
184
+ yield history
185
+ return
186
+
187
+ history = history or []
188
+
189
+ # Build conversation context
190
+ system = "You are Axon, an expert AI coding assistant. Be helpful, concise, and provide working code examples when appropriate."
191
+ conversation = ""
192
+ for user_msg, assistant_msg in history[-5:]: # Last 5 turns
193
+ conversation += f"<|im_start|>user\n{user_msg}<|im_end|>\n<|im_start|>assistant\n{assistant_msg}<|im_end|>\n"
194
+
195
+ prompt = f"<|im_start|>system\n{system}<|im_end|>\n{conversation}<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
196
 
197
+ response = ""
198
+ history.append([message, ""])
 
199
 
200
+ for chunk in generate_stream(prompt, model, max_tokens, temperature):
201
+ response += chunk
202
+ history[-1][1] = response
203
+ yield history
204
+
205
+ yield history
206
 
207
+ def generate_code(description, language, model, max_tokens):
208
+ if not description.strip():
209
+ return "Please provide a description."
210
 
211
+ system = f"You are an expert {language} programmer. Generate clean, well-commented, production-ready code."
212
+ prompt = format_prompt(system, f"Generate {language} code for: {description}")
213
+ return generate_response(prompt, model, max_tokens)
214
+
215
+ def explain_code(code, model, detail_level, max_tokens):
216
+ if not code.strip():
217
+ return "Please provide code to explain."
218
 
219
+ detail_map = {
220
+ "Brief": "Give a brief 2-3 sentence explanation.",
221
+ "Normal": "Explain the code clearly with key points.",
222
+ "Detailed": "Provide a comprehensive explanation covering logic, patterns, and potential improvements."
223
+ }
224
 
225
+ system = "You are an expert code explainer. " + detail_map.get(detail_level, detail_map["Normal"])
226
+ prompt = format_prompt(system, f"Explain this code:\n\n```\n{code}\n```")
227
+ return generate_response(prompt, model, max_tokens)
228
 
229
+ def debug_code(code, error, model, max_tokens):
230
+ if not code.strip():
231
+ return "Please provide code to debug."
232
+
233
+ system = "You are an expert debugger. Identify bugs, explain the issues, and provide corrected code."
234
+ user = f"Debug this code:\n\n```\n{code}\n```"
235
+ if error.strip():
236
+ user += f"\n\nError message:\n{error}"
237
+
238
+ prompt = format_prompt(system, user)
239
+ return generate_response(prompt, model, max_tokens)
240
 
241
+ def review_code(code, model, max_tokens):
242
+ if not code.strip():
243
+ return "Please provide code to review."
244
 
245
+ system = """You are a senior code reviewer. Review the code for:
246
+ 1. Code quality and readability
247
+ 2. Potential bugs or issues
248
+ 3. Security vulnerabilities
249
+ 4. Performance concerns
250
+ 5. Best practices
251
+ Provide specific, actionable feedback."""
252
 
253
+ prompt = format_prompt(system, f"Review this code:\n\n```\n{code}\n```")
254
+ return generate_response(prompt, model, max_tokens)
255
+
256
+ # --- ADVANCED TOOLS ---
257
+ def security_scan(code, model, max_tokens):
258
+ if not code.strip():
259
+ return "Please provide code to scan."
260
 
261
+ system = """You are a security expert. Scan the code for vulnerabilities including:
262
+ - SQL injection
263
+ - XSS (Cross-site scripting)
264
+ - CSRF vulnerabilities
265
+ - Insecure data handling
266
+ - Authentication issues
267
+ - Input validation problems
268
+ - Secrets/credentials exposure
269
+ Rate severity (Critical/High/Medium/Low) and provide fixes."""
 
 
 
270
 
271
+ prompt = format_prompt(system, f"Security scan this code:\n\n```\n{code}\n```")
272
+ return generate_response(prompt, model, max_tokens)
273
+
274
+ def analyze_complexity(code, model, max_tokens):
275
+ if not code.strip():
276
+ return "Please provide code to analyze."
277
 
278
+ system = """You are an algorithms expert. Analyze the code complexity:
279
+ 1. Time complexity (Big O notation)
280
+ 2. Space complexity (Big O notation)
281
+ 3. Explain the analysis step by step
282
+ 4. Suggest optimizations if possible"""
283
+
284
+ prompt = format_prompt(system, f"Analyze complexity:\n\n```\n{code}\n```")
285
+ return generate_response(prompt, model, max_tokens)
 
286
 
287
+ def convert_code(code, from_lang, to_lang, model, max_tokens):
288
+ if not code.strip():
289
+ return "Please provide code to convert."
 
 
290
 
291
+ system = f"You are an expert polyglot programmer. Convert code from {from_lang} to {to_lang}. Preserve functionality and use idiomatic patterns for the target language."
292
+ prompt = format_prompt(system, f"Convert this {from_lang} code to {to_lang}:\n\n```\n{code}\n```")
293
+ return generate_response(prompt, model, max_tokens)
294
+
295
+ def generate_tests(code, language, framework, model, max_tokens):
296
+ if not code.strip():
297
+ return "Please provide code to test."
298
 
299
+ system = f"You are a testing expert. Generate comprehensive {framework} unit tests for {language} code. Include edge cases, error cases, and happy path tests."
300
+ prompt = format_prompt(system, f"Generate {framework} tests for:\n\n```\n{code}\n```")
301
+ return generate_response(prompt, model, max_tokens)
302
+
303
+ def document_code(code, language, style, model, max_tokens):
304
+ if not code.strip():
305
+ return "Please provide code to document."
306
+
307
+ style_map = {
308
+ "Docstrings": "Add comprehensive docstrings to all functions/classes.",
309
+ "Inline Comments": "Add helpful inline comments explaining the logic.",
310
+ "Both": "Add both docstrings and inline comments."
311
+ }
312
+
313
+ system = f"You are a documentation expert. {style_map.get(style, style_map['Both'])} Use {language} documentation conventions."
314
+ prompt = format_prompt(system, f"Document this code:\n\n```\n{code}\n```")
315
+ return generate_response(prompt, model, max_tokens)
316
+
317
+ def optimize_code(code, language, focus, model, max_tokens):
318
+ if not code.strip():
319
+ return "Please provide code to optimize."
320
+
321
+ system = f"You are a performance optimization expert. Optimize the {language} code focusing on {focus}. Show the optimized code and explain the improvements."
322
+ prompt = format_prompt(system, f"Optimize this code for {focus}:\n\n```\n{code}\n```")
323
+ return generate_response(prompt, model, max_tokens)
324
+
325
+ def code_diff(code1, code2, model, max_tokens):
326
+ if not code1.strip() or not code2.strip():
327
+ return "Please provide both code snippets to compare."
328
+
329
+ system = "You are a code analysis expert. Compare the two code snippets and explain the differences, which is better, and why."
330
+ prompt = format_prompt(system, f"Compare these code snippets:\n\n**Code 1:**\n```\n{code1}\n```\n\n**Code 2:**\n```\n{code2}\n```")
331
+ return generate_response(prompt, model, max_tokens)
332
+
333
+ def to_pseudocode(code, output_type, model, max_tokens):
334
+ if not code.strip():
335
+ return "Please provide code to convert."
336
+
337
+ if output_type == "Pseudocode":
338
+ system = "Convert the code to clear, readable pseudocode that anyone can understand."
339
  else:
340
+ system = "Convert the code to a text-based flowchart using ASCII art or a structured description."
 
341
 
342
+ prompt = format_prompt(system, f"Convert to {output_type}:\n\n```\n{code}\n```")
343
+ return generate_response(prompt, model, max_tokens)
344
+
345
+ def interview_challenge(topic, difficulty, language, model, max_tokens):
346
+ system = f"You are a technical interviewer. Create a {difficulty} {language} coding challenge about {topic}. Include: problem statement, examples, constraints, hints, and a solution with explanation."
347
+ prompt = format_prompt(system, f"Create a {difficulty} {topic} challenge in {language}")
348
+ return generate_response(prompt, model, max_tokens)
349
+
350
+ # --- BUILDERS ---
351
+ def build_sql(description, sql_type, model, max_tokens):
352
+ if not description.strip():
353
+ return "Please describe what SQL you need."
354
+
355
+ system = f"You are a SQL expert. Generate {sql_type} SQL queries. Include comments explaining the query."
356
+ prompt = format_prompt(system, f"Generate SQL for: {description}")
357
+ return generate_response(prompt, model, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
 
359
+ def build_shell(description, shell_type, model, max_tokens):
360
+ if not description.strip():
361
+ return "Please describe what command you need."
362
+
363
+ system = f"You are a {shell_type} expert. Generate safe, well-commented shell commands. Warn about any dangerous operations."
364
+ prompt = format_prompt(system, f"Generate {shell_type} command for: {description}")
365
+ return generate_response(prompt, model, max_tokens)
366
 
367
+ def build_cron(description, model, max_tokens):
368
+ if not description.strip():
369
+ return "Please describe the schedule you need."
370
 
371
+ system = "You are a cron expert. Generate cron expressions with clear explanations. Include the cron format: minute hour day month weekday"
372
+ prompt = format_prompt(system, f"Generate cron expression for: {description}")
373
+ return generate_response(prompt, model, max_tokens)
374
+
375
+ def build_regex(description, model, max_tokens):
376
+ if not description.strip():
377
+ return "Please describe the pattern you need."
 
 
 
 
378
 
379
+ system = "You are a regex expert. Generate regular expressions with explanations and test examples. Support multiple regex flavors if relevant."
380
+ prompt = format_prompt(system, f"Generate regex for: {description}")
381
+ return generate_response(prompt, model, max_tokens)
382
+
383
+ def build_api(description, framework, model, max_tokens):
384
+ if not description.strip():
385
+ return "Please describe the API endpoint you need."
386
 
387
+ system = f"You are an API expert. Generate a complete {framework} REST API endpoint with error handling, validation, and documentation."
388
+ prompt = format_prompt(system, f"Generate {framework} API endpoint for: {description}")
389
+ return generate_response(prompt, model, max_tokens)
390
+
391
+ # --- DATA TOOLS ---
392
+ def generate_mock_data(schema, count, format_type, model, max_tokens):
393
+ if not schema.strip():
394
+ return "Please provide a schema or description."
395
 
396
+ system = f"You are a data generation expert. Generate {count} realistic mock data records in {format_type} format based on the schema."
397
+ prompt = format_prompt(system, f"Generate {count} mock records in {format_type}:\n\nSchema: {schema}")
398
+ return generate_response(prompt, model, max_tokens)
399
 
400
+ def convert_data_format(data, from_format, to_format, model, max_tokens):
401
+ if not data.strip():
402
+ return "Please provide data to convert."
403
+
404
+ system = f"Convert the data from {from_format} to {to_format}. Preserve all information and use proper formatting."
405
+ prompt = format_prompt(system, f"Convert from {from_format} to {to_format}:\n\n```\n{data}\n```")
406
+ return generate_response(prompt, model, max_tokens)
407
+
408
+ # --- NEW v26 TOOLS ---
409
+ def refactor_code(code, language, pattern, model, max_tokens):
410
+ if not code.strip():
411
+ return "Please provide code to refactor."
412
+
413
+ system = f"You are a software architect. Refactor the {language} code using {pattern} patterns. Explain the improvements and show before/after."
414
+ prompt = format_prompt(system, f"Refactor using {pattern}:\n\n```\n{code}\n```")
415
+ return generate_response(prompt, model, max_tokens)
416
+
417
+ def generate_benchmark(code, language, model, max_tokens):
418
+ if not code.strip():
419
+ return "Please provide code to benchmark."
420
+
421
+ system = f"You are a performance testing expert. Generate comprehensive {language} benchmark code to measure performance. Include setup, warmup, multiple iterations, and statistics."
422
+ prompt = format_prompt(system, f"Generate benchmark for:\n\n```\n{code}\n```")
423
+ return generate_response(prompt, model, max_tokens)
424
+
425
+ def analyze_dependencies(code, language, model, max_tokens):
426
+ if not code.strip():
427
+ return "Please provide code to analyze."
428
+
429
+ system = f"You are a dependency analysis expert. Analyze the {language} code for:
430
+ 1. Direct imports/dependencies
431
+ 2. Potential circular dependencies
432
+ 3. Unused imports
433
+ 4. Missing dependencies
434
+ 5. Version compatibility concerns
435
+ 6. Security advisories for known packages"
436
+
437
+ prompt = format_prompt(system, f"Analyze dependencies:\n\n```\n{code}\n```")
438
+ return generate_response(prompt, model, max_tokens)
439
+
440
+ def generate_changelog(diff_or_commits, version, model, max_tokens):
441
+ if not diff_or_commits.strip():
442
+ return "Please provide diff or commit messages."
443
+
444
+ system = """You are a technical writer. Generate a professional changelog entry with:
445
+ - Version number and date
446
+ - Categories: Added, Changed, Fixed, Removed, Security
447
+ - Clear, user-friendly descriptions
448
+ - Breaking changes highlighted"""
449
+
450
+ prompt = format_prompt(system, f"Generate changelog for version {version}:\n\n{diff_or_commits}")
451
+ return generate_response(prompt, model, max_tokens)
452
+
453
+ def suggest_improvements(code, language, model, max_tokens):
454
+ if not code.strip():
455
+ return "Please provide code to analyze."
456
+
457
+ system = f"""You are a senior {language} developer. Provide actionable improvement suggestions:
458
+ 1. Code quality improvements
459
+ 2. Performance optimizations
460
+ 3. Better error handling
461
+ 4. Modern language features to use
462
+ 5. Design pattern recommendations
463
+ 6. Testing suggestions
464
+ Rate each suggestion by impact (High/Medium/Low) and effort."""
465
+
466
+ prompt = format_prompt(system, f"Suggest improvements:\n\n```\n{code}\n```")
467
+ return generate_response(prompt, model, max_tokens)
468
+
469
+ # ===== UI =====
470
+ def create_ui():
471
+ # Check cached models
472
+ cached = get_cached_models()
473
+ total_models = len(MODELS)
474
+
475
+ css = """
476
+ .main-header { text-align: center; margin-bottom: 20px; }
477
+ .tool-description { color: #666; font-size: 0.9em; margin-bottom: 10px; }
478
+ .status-bar { padding: 10px; border-radius: 8px; margin-bottom: 15px; }
479
+ """
480
+
481
+ with gr.Blocks(title="Axon v26", css=css) as demo:
482
+ # Header
483
+ gr.HTML("""
484
+ <div class="main-header">
485
+ <h1>⚡ Axon v26</h1>
486
+ <p>The Ultimate Free AI Coding Assistant • 5 Models • 25 Tools • 100% Local</p>
487
+ </div>
488
+ """)
489
 
490
+ # Status bar
491
+ status_emoji = "🟢" if cached else "🟡"
492
+ gr.HTML(f"""
493
+ <div class="status-bar" style="background: linear-gradient(135deg, #667eea22, #764ba222);">
494
+ {status_emoji} <strong>{len(cached)}/{total_models}</strong> models cached •
495
+ Models download on first use (~1-9GB each)
496
+ </div>
497
+ """)
498
 
499
+ # Global controls
500
+ with gr.Row():
501
+ model_dropdown = gr.Dropdown(
502
+ choices=list(MODELS.keys()),
503
+ value=list(MODELS.keys())[2], # Default to 3B
504
+ label="🤖 Model",
505
+ scale=2
506
+ )
507
+ max_tokens = gr.Slider(256, 4096, value=2048, step=256, label="Max Tokens", scale=1)
508
 
509
+ # Tabs
510
+ with gr.Tabs():
511
+ # === CHAT TAB ===
512
+ with gr.Tab("💬 Chat"):
513
+ gr.HTML("<p class='tool-description'>Have a conversation about code, get help, ask questions.</p>")
514
+ chatbot = gr.Chatbot(height=400)
515
+ with gr.Row():
516
+ msg = gr.Textbox(placeholder="Ask me anything about code...", scale=4, show_label=False)
517
+ send_btn = gr.Button("Send", variant="primary")
518
+ with gr.Row():
519
+ temperature = gr.Slider(0, 1, value=0.7, step=0.1, label="Temperature")
520
+ audio_input = gr.Audio(type="filepath", label="🎤 Voice Input")
521
+ transcribe_btn = gr.Button("Transcribe")
522
+ clear_btn = gr.Button("Clear Chat")
523
+
524
+ # === GENERATE TAB ===
525
+ with gr.Tab("⚡ Generate"):
526
+ gr.HTML("<p class='tool-description'>Describe what you want, get working code.</p>")
527
+ gen_prompt = gr.Textbox(lines=3, placeholder="Describe the code you want...", label="Description")
528
+ gen_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
529
+ gen_btn = gr.Button("Generate", variant="primary")
530
+ gen_output = gr.Code(label="Generated Code", language="python")
531
+
532
+ # === EXPLAIN TAB ===
533
+ with gr.Tab("🔍 Explain"):
534
+ gr.HTML("<p class='tool-description'>Understand any code with detailed explanations.</p>")
535
+ explain_input = gr.Code(lines=10, label="Code to Explain", language="python")
536
+ explain_detail = gr.Radio(["Brief", "Normal", "Detailed"], value="Normal", label="Detail Level")
537
+ explain_btn = gr.Button("Explain", variant="primary")
538
+ explain_output = gr.Markdown(label="Explanation")
539
+
540
+ # === DEBUG TAB ===
541
+ with gr.Tab("🔧 Debug"):
542
+ gr.HTML("<p class='tool-description'>Find and fix bugs with AI assistance.</p>")
543
+ debug_input = gr.Code(lines=10, label="Buggy Code", language="python")
544
+ debug_error = gr.Textbox(lines=3, placeholder="Paste error message (optional)", label="Error Message")
545
+ debug_btn = gr.Button("Debug", variant="primary")
546
+ debug_output = gr.Markdown(label="Debug Results")
547
+
548
+ # === REVIEW TAB ===
549
+ with gr.Tab("📋 Review"):
550
+ gr.HTML("<p class='tool-description'>Get comprehensive code review feedback.</p>")
551
+ review_input = gr.Code(lines=10, label="Code to Review", language="python")
552
+ review_btn = gr.Button("Review", variant="primary")
553
+ review_output = gr.Markdown(label="Review Results")
554
+
555
+ # === SECURITY TAB ===
556
+ with gr.Tab("🔐 Security"):
557
+ gr.HTML("<p class='tool-description'>Scan code for security vulnerabilities.</p>")
558
+ security_input = gr.Code(lines=10, label="Code to Scan", language="python")
559
+ security_btn = gr.Button("Scan", variant="primary")
560
+ security_output = gr.Markdown(label="Security Report")
561
+
562
+ # === COMPLEXITY TAB ===
563
+ with gr.Tab("📊 Complexity"):
564
+ gr.HTML("<p class='tool-description'>Analyze time and space complexity (Big O).</p>")
565
+ complexity_input = gr.Code(lines=10, label="Code to Analyze", language="python")
566
+ complexity_btn = gr.Button("Analyze", variant="primary")
567
+ complexity_output = gr.Markdown(label="Complexity Analysis")
568
+
569
+ # === CONVERT TAB ===
570
+ with gr.Tab("🔄 Convert"):
571
+ gr.HTML("<p class='tool-description'>Translate code between programming languages.</p>")
572
+ convert_input = gr.Code(lines=10, label="Code to Convert", language="python")
573
+ with gr.Row():
574
+ convert_from = gr.Dropdown(choices=LANGUAGES, value="Python", label="From")
575
+ convert_to = gr.Dropdown(choices=LANGUAGES, value="JavaScript", label="To")
576
+ convert_btn = gr.Button("Convert", variant="primary")
577
+ convert_output = gr.Code(label="Converted Code", language="javascript")
578
+
579
+ # === TEST TAB ===
580
+ with gr.Tab("🧪 Test"):
581
+ gr.HTML("<p class='tool-description'>Generate comprehensive unit tests.</p>")
582
+ test_input = gr.Code(lines=10, label="Code to Test", language="python")
583
+ with gr.Row():
584
+ test_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
585
+ test_fw = gr.Dropdown(choices=["pytest", "unittest", "Jest", "Mocha", "JUnit", "RSpec"], value="pytest", label="Framework")
586
+ test_btn = gr.Button("Generate Tests", variant="primary")
587
+ test_output = gr.Code(label="Generated Tests", language="python")
588
+
589
+ # === DOCUMENT TAB ===
590
+ with gr.Tab("📝 Document"):
591
+ gr.HTML("<p class='tool-description'>Add documentation to your code.</p>")
592
+ doc_input = gr.Code(lines=10, label="Code to Document", language="python")
593
+ with gr.Row():
594
+ doc_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
595
+ doc_style = gr.Dropdown(choices=["Docstrings", "Inline Comments", "Both"], value="Both", label="Style")
596
+ doc_btn = gr.Button("Document", variant="primary")
597
+ doc_output = gr.Code(label="Documented Code", language="python")
598
+
599
+ # === OPTIMIZE TAB ===
600
+ with gr.Tab("🚀 Optimize"):
601
+ gr.HTML("<p class='tool-description'>Improve code performance.</p>")
602
+ opt_input = gr.Code(lines=10, label="Code to Optimize", language="python")
603
+ with gr.Row():
604
+ opt_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
605
+ opt_focus = gr.Dropdown(choices=["Speed", "Memory", "Readability", "All"], value="All", label="Focus")
606
+ opt_btn = gr.Button("Optimize", variant="primary")
607
+ opt_output = gr.Markdown(label="Optimized Code")
608
+
609
+ # === DIFF TAB ===
610
+ with gr.Tab("🔀 Diff"):
611
+ gr.HTML("<p class='tool-description'>Compare two code snippets.</p>")
612
+ with gr.Row():
613
+ diff_code1 = gr.Code(lines=8, label="Code 1", language="python")
614
+ diff_code2 = gr.Code(lines=8, label="Code 2", language="python")
615
+ diff_btn = gr.Button("Compare", variant="primary")
616
+ diff_output = gr.Markdown(label="Comparison")
617
+
618
+ # === PSEUDOCODE TAB ===
619
+ with gr.Tab("📐 Pseudo"):
620
+ gr.HTML("<p class='tool-description'>Convert code to pseudocode or flowcharts.</p>")
621
+ pseudo_input = gr.Code(lines=10, label="Code", language="python")
622
+ pseudo_type = gr.Radio(["Pseudocode", "Flowchart"], value="Pseudocode", label="Output Type")
623
+ pseudo_btn = gr.Button("Convert", variant="primary")
624
+ pseudo_output = gr.Markdown(label="Output")
625
+
626
+ # === INTERVIEW TAB ===
627
+ with gr.Tab("🎓 Interview"):
628
+ gr.HTML("<p class='tool-description'>Generate coding interview challenges.</p>")
629
+ with gr.Row():
630
+ interview_topic = gr.Textbox(placeholder="e.g., binary trees, dynamic programming", label="Topic")
631
+ interview_diff = gr.Dropdown(choices=["Easy", "Medium", "Hard"], value="Medium", label="Difficulty")
632
+ interview_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
633
+ interview_btn = gr.Button("Generate Challenge", variant="primary")
634
+ interview_output = gr.Markdown(label="Challenge")
635
+
636
+ # === SQL TAB ===
637
+ with gr.Tab("🗄️ SQL"):
638
+ gr.HTML("<p class='tool-description'>Generate SQL queries from natural language.</p>")
639
+ sql_desc = gr.Textbox(lines=3, placeholder="Describe your query...", label="Description")
640
+ sql_type = gr.Dropdown(choices=["MySQL", "PostgreSQL", "SQLite", "SQL Server", "Oracle"], value="PostgreSQL", label="Database")
641
+ sql_btn = gr.Button("Generate SQL", variant="primary")
642
+ sql_output = gr.Code(label="Generated SQL", language="sql")
643
+
644
+ # === SHELL TAB ===
645
+ with gr.Tab("🐚 Shell"):
646
+ gr.HTML("<p class='tool-description'>Generate shell commands from descriptions.</p>")
647
+ shell_desc = gr.Textbox(lines=3, placeholder="Describe what you want to do...", label="Description")
648
+ shell_type = gr.Dropdown(choices=["Bash", "PowerShell", "Zsh", "Fish"], value="Bash", label="Shell")
649
+ shell_btn = gr.Button("Generate", variant="primary")
650
+ shell_output = gr.Code(label="Generated Command", language="bash")
651
+
652
+ # === CRON TAB ===
653
+ with gr.Tab("⏰ Cron"):
654
+ gr.HTML("<p class='tool-description'>Generate cron schedule expressions.</p>")
655
+ cron_desc = gr.Textbox(lines=2, placeholder="e.g., Every Monday at 9am", label="Schedule Description")
656
+ cron_btn = gr.Button("Generate", variant="primary")
657
+ cron_output = gr.Markdown(label="Cron Expression")
658
+
659
+ # === REGEX TAB ===
660
+ with gr.Tab("🎯 Regex"):
661
+ gr.HTML("<p class='tool-description'>Generate regular expressions with explanations.</p>")
662
+ regex_desc = gr.Textbox(lines=2, placeholder="e.g., Match email addresses", label="Pattern Description")
663
+ regex_btn = gr.Button("Generate", variant="primary")
664
+ regex_output = gr.Markdown(label="Regex Pattern")
665
+
666
+ # === API TAB ===
667
+ with gr.Tab("🔗 API"):
668
+ gr.HTML("<p class='tool-description'>Generate REST API endpoint boilerplate.</p>")
669
+ api_desc = gr.Textbox(lines=3, placeholder="Describe your API endpoint...", label="Description")
670
+ api_fw = gr.Dropdown(choices=["FastAPI", "Flask", "Express", "Django", "Spring Boot", "Go Gin"], value="FastAPI", label="Framework")
671
+ api_btn = gr.Button("Generate", variant="primary")
672
+ api_output = gr.Code(label="Generated API", language="python")
673
+
674
+ # === MOCK DATA TAB ===
675
+ with gr.Tab("📦 Mock"):
676
+ gr.HTML("<p class='tool-description'>Generate realistic test data.</p>")
677
+ mock_schema = gr.Textbox(lines=3, placeholder="e.g., users with name, email, age", label="Schema Description")
678
+ with gr.Row():
679
+ mock_count = gr.Number(value=5, label="Count", precision=0)
680
+ mock_format = gr.Dropdown(choices=["JSON", "CSV", "SQL INSERT", "YAML"], value="JSON", label="Format")
681
+ mock_btn = gr.Button("Generate", variant="primary")
682
+ mock_output = gr.Code(label="Generated Data", language="json")
683
+
684
+ # === FORMAT TAB ===
685
+ with gr.Tab("🔄 Format"):
686
+ gr.HTML("<p class='tool-description'>Convert between data formats.</p>")
687
+ format_input = gr.Code(lines=10, label="Input Data", language="json")
688
+ with gr.Row():
689
+ format_from = gr.Dropdown(choices=["JSON", "YAML", "XML", "CSV", "TOML"], value="JSON", label="From")
690
+ format_to = gr.Dropdown(choices=["JSON", "YAML", "XML", "CSV", "TOML"], value="YAML", label="To")
691
+ format_btn = gr.Button("Convert", variant="primary")
692
+ format_output = gr.Code(label="Converted Data", language="yaml")
693
+
694
+ # === REFACTOR TAB (NEW) ===
695
+ with gr.Tab("🎨 Refactor"):
696
+ gr.HTML("<p class='tool-description'>Restructure code using design patterns.</p>")
697
+ refactor_input = gr.Code(lines=10, label="Code to Refactor", language="python")
698
+ with gr.Row():
699
+ refactor_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
700
+ refactor_pattern = gr.Dropdown(choices=["Clean Code", "SOLID", "DRY", "Factory", "Singleton", "Observer", "Strategy"], value="Clean Code", label="Pattern")
701
+ refactor_btn = gr.Button("Refactor", variant="primary")
702
+ refactor_output = gr.Markdown(label="Refactored Code")
703
+
704
+ # === BENCHMARK TAB (NEW) ===
705
+ with gr.Tab("📊 Bench"):
706
+ gr.HTML("<p class='tool-description'>Generate performance benchmark code.</p>")
707
+ bench_input = gr.Code(lines=10, label="Code to Benchmark", language="python")
708
+ bench_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
709
+ bench_btn = gr.Button("Generate Benchmark", variant="primary")
710
+ bench_output = gr.Code(label="Benchmark Code", language="python")
711
+
712
+ # === DEPENDENCIES TAB (NEW) ===
713
+ with gr.Tab("🔗 Deps"):
714
+ gr.HTML("<p class='tool-description'>Analyze imports and dependencies.</p>")
715
+ deps_input = gr.Code(lines=10, label="Code to Analyze", language="python")
716
+ deps_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
717
+ deps_btn = gr.Button("Analyze", variant="primary")
718
+ deps_output = gr.Markdown(label="Dependency Analysis")
719
+
720
+ # === CHANGELOG TAB (NEW) ===
721
+ with gr.Tab("📋 Change"):
722
+ gr.HTML("<p class='tool-description'>Generate changelogs from diffs or commits.</p>")
723
+ changelog_input = gr.Textbox(lines=10, placeholder="Paste git diff, commit messages, or describe changes...", label="Changes")
724
+ changelog_version = gr.Textbox(value="1.0.0", label="Version")
725
+ changelog_btn = gr.Button("Generate Changelog", variant="primary")
726
+ changelog_output = gr.Markdown(label="Changelog")
727
+
728
+ # === SUGGEST TAB (NEW) ===
729
+ with gr.Tab("💡 Suggest"):
730
+ gr.HTML("<p class='tool-description'>Get AI-powered improvement suggestions.</p>")
731
+ suggest_input = gr.Code(lines=10, label="Code to Analyze", language="python")
732
+ suggest_lang = gr.Dropdown(choices=LANGUAGES, value="Python", label="Language")
733
+ suggest_btn = gr.Button("Get Suggestions", variant="primary")
734
+ suggest_output = gr.Markdown(label="Suggestions")
735
 
736
+ # Footer
737
+ gr.HTML("""
738
+ <div style="text-align: center; margin-top: 20px; padding: 15px; background: linear-gradient(135deg, #667eea11, #764ba211); border-radius: 10px;">
739
+ <p><strong>⚡ Axon v26</strong> • Built with ❤️ by <a href="https://huggingface.co/AIencoder" target="_blank">AIencoder</a></p>
740
+ <p style="font-size: 0.85em; color: #666;">
741
+ <a href="https://huggingface.co/datasets/AIencoder/llama-cpp-wheels" target="_blank">🛞 Pre-built Wheels</a> •
742
+ 100% Local No API Keys • MIT License
743
+ </p>
744
+ </div>
745
+ """)
746
 
747
+ # === EVENT HANDLERS ===
 
 
 
 
 
 
 
 
 
748
 
749
+ # Chat
750
+ def respond(message, history, model, temp, tokens):
751
+ history = history or []
752
+ for updated_history in chat_stream(message, history, model, temp, tokens):
753
+ yield updated_history, ""
 
 
 
 
 
754
 
755
+ msg.submit(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
756
+ send_btn.click(respond, [msg, chatbot, model_dropdown, temperature, max_tokens], [chatbot, msg])
757
+ clear_btn.click(lambda: [], None, chatbot)
758
+ transcribe_btn.click(transcribe_audio, audio_input, msg)
 
 
 
 
 
 
759
 
760
+ # Core tools
761
+ gen_btn.click(generate_code, [gen_prompt, gen_lang, model_dropdown, max_tokens], gen_output)
762
+ explain_btn.click(explain_code, [explain_input, model_dropdown, explain_detail, max_tokens], explain_output)
763
+ debug_btn.click(debug_code, [debug_input, debug_error, model_dropdown, max_tokens], debug_output)
764
+ review_btn.click(review_code, [review_input, model_dropdown, max_tokens], review_output)
 
 
 
765
 
766
+ # Advanced tools
767
+ security_btn.click(security_scan, [security_input, model_dropdown, max_tokens], security_output)
768
+ complexity_btn.click(analyze_complexity, [complexity_input, model_dropdown, max_tokens], complexity_output)
769
+ convert_btn.click(convert_code, [convert_input, convert_from, convert_to, model_dropdown, max_tokens], convert_output)
770
+ test_btn.click(generate_tests, [test_input, test_lang, test_fw, model_dropdown, max_tokens], test_output)
771
+ doc_btn.click(document_code, [doc_input, doc_lang, doc_style, model_dropdown, max_tokens], doc_output)
772
+ opt_btn.click(optimize_code, [opt_input, opt_lang, opt_focus, model_dropdown, max_tokens], opt_output)
773
+ diff_btn.click(code_diff, [diff_code1, diff_code2, model_dropdown, max_tokens], diff_output)
774
+ pseudo_btn.click(to_pseudocode, [pseudo_input, pseudo_type, model_dropdown, max_tokens], pseudo_output)
775
+ interview_btn.click(interview_challenge, [interview_topic, interview_diff, interview_lang, model_dropdown, max_tokens], interview_output)
776
 
777
+ # Builders
778
+ sql_btn.click(build_sql, [sql_desc, sql_type, model_dropdown, max_tokens], sql_output)
779
+ shell_btn.click(build_shell, [shell_desc, shell_type, model_dropdown, max_tokens], shell_output)
780
+ cron_btn.click(build_cron, [cron_desc, model_dropdown, max_tokens], cron_output)
781
+ regex_btn.click(build_regex, [regex_desc, model_dropdown, max_tokens], regex_output)
782
+ api_btn.click(build_api, [api_desc, api_fw, model_dropdown, max_tokens], api_output)
 
 
 
 
783
 
784
+ # Data tools
785
+ mock_btn.click(generate_mock_data, [mock_schema, mock_count, mock_format, model_dropdown, max_tokens], mock_output)
786
+ format_btn.click(convert_data_format, [format_input, format_from, format_to, model_dropdown, max_tokens], format_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
 
788
+ # NEW v26 tools
789
+ refactor_btn.click(refactor_code, [refactor_input, refactor_lang, refactor_pattern, model_dropdown, max_tokens], refactor_output)
790
+ bench_btn.click(generate_benchmark, [bench_input, bench_lang, model_dropdown, max_tokens], bench_output)
791
+ deps_btn.click(analyze_dependencies, [deps_input, deps_lang, model_dropdown, max_tokens], deps_output)
792
+ changelog_btn.click(generate_changelog, [changelog_input, changelog_version, model_dropdown, max_tokens], changelog_output)
793
+ suggest_btn.click(suggest_improvements, [suggest_input, suggest_lang, model_dropdown, max_tokens], suggest_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
 
795
+ return demo
796
+
797
+ # ===== MAIN =====
798
+ if __name__ == "__main__":
799
+ print("⚡ Axon v26 - The FINAL Version")
800
+ print("=" * 40)
801
+
802
+ init_directories()
803
+ init_whisper()
804
+
805
+ cached = get_cached_models()
806
+ print(f"📦 Cached models: {len(cached)}/{len(MODELS)}")
807
+ for m in cached:
808
+ print(f" ✅ {m}")
809
+
810
+ print("\n🚀 Starting Axon...")
811
+ demo = create_ui()
812
+ demo.launch(server_name="0.0.0.0", server_port=7860)