MegaTronX commited on
Commit
122833b
·
verified ·
1 Parent(s): 08bbcbd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -60
app.py CHANGED
@@ -1,10 +1,10 @@
1
- import spaces
2
  import os
3
  import re
4
  import json
5
  import tempfile
6
  import zipfile
7
  import gradio as gr
 
8
  from huggingface_hub import hf_hub_download
9
 
10
  # ---- LLM: llama.cpp via llama_cpp_agent ----
@@ -15,11 +15,9 @@ from llama_cpp_agent.providers import LlamaCppPythonProvider
15
  # ----------------------
16
  # Model configuration
17
  # ----------------------
18
- # You can change these defaults in the UI
19
  DEFAULT_REPO_ID = "tHottie/NeuralDaredevil-8B-abliterated-Q4_K_M-GGUF"
20
  DEFAULT_FILENAME = "neuraldaredevil-8b-abliterated-q4_k_m-imat.gguf"
21
  MODELS_DIR = "models"
22
-
23
  os.makedirs(MODELS_DIR, exist_ok=True)
24
 
25
  def ensure_model(repo_id: str, filename: str) -> str:
@@ -28,13 +26,16 @@ def ensure_model(repo_id: str, filename: str) -> str:
28
  hf_hub_download(repo_id=repo_id, filename=filename, local_dir=MODELS_DIR)
29
  return local_path
30
 
31
- def build_agent(model_path: str, n_ctx=8192, n_gpu_layers=81, n_batch=1024, flash_attn=True):
 
 
 
32
  llm = Llama(
33
  model_path=model_path,
34
- n_ctx=n_ctx,
35
- n_gpu_layers=n_gpu_layers,
36
- n_batch=n_batch,
37
- flash_attn=flash_attn,
38
  )
39
  provider = LlamaCppPythonProvider(llm)
40
  agent = LlamaCppAgent(
@@ -52,21 +53,16 @@ def build_agent(model_path: str, n_ctx=8192, n_gpu_layers=81, n_batch=1024, flas
52
  predefined_messages_formatter_type=MessagesFormatterType.GEMMA_2,
53
  debug_output=False
54
  )
55
- return agent, provider
56
 
57
- JSON_FALLBACK_NAME = "project.txt"
58
-
59
- @spaces.GPU(duration=120)
60
- def call_llm_manifest(agent, provider, text, temperature=0.2, top_p=0.9, top_k=40, repeat_penalty=1.1, max_tokens=2048):
61
- # Instruction prompt. Model must respond with STRICT JSON.
62
  prompt = f"""
63
- Read the following AI project description and return ONLY JSON.
64
  Output schema (strict):
65
  [{{"filename": "server.js", "content": "// code..."}}]
66
 
67
  AI project description:
68
- {text}
69
  """
 
70
  settings = provider.get_provider_default_settings()
71
  settings.temperature = float(temperature)
72
  settings.top_p = float(top_p)
@@ -76,38 +72,32 @@ AI project description:
76
  settings.stream = False
77
 
78
  out = agent.get_chat_response(prompt, llm_sampling_settings=settings, print_output=False)
79
- # Try to extract a JSON array from the output robustly
80
- json_text = None
81
  try:
82
- # Prefer the largest bracketed array slice
83
- start = out.find('[')
84
- end = out.rfind(']')
85
- if start != -1 and end != -1 and end > start:
86
- json_text = out[start:end+1]
87
- manifest = json.loads(json_text)
88
  else:
89
- raise ValueError("No JSON array found")
90
  except Exception:
91
- # Fallback: single-file package of raw output for transparency
92
- manifest = [ {"filename": JSON_FALLBACK_NAME, "content": out} ]
93
- return manifest
 
 
 
 
94
 
95
  def naive_regex_merge(text):
96
- """
97
- Heuristic backup that maps code fences to probable filenames by scanning nearby lines.
98
- This runs only when the model output is a single fallback file OR user ticks 'Force Heuristic Merge'.
99
- """
100
  blocks = []
101
- # Find all triple-backtick code blocks
102
  code_pattern = re.compile(r"```([a-zA-Z0-9]*)\n(.*?)```", re.DOTALL)
103
- # Find filename candidates in preceding lines such as '### STEP: server.js' or '`server.js`'
104
  lines = text.splitlines()
105
  candidates = []
106
- for i, line in enumerate(lines):
107
- m = re.search(r"([A-Za-z0-9_\\-./]+?\\.[A-Za-z0-9]+)", line)
108
  if m:
109
  candidates.append(m.group(1))
110
-
111
  for idx, m in enumerate(code_pattern.finditer(text)):
112
  lang = m.group(1) or "txt"
113
  code = m.group(2)
@@ -120,7 +110,7 @@ def create_zip_from_manifest(manifest):
120
  zip_path = os.path.join(temp_dir, "project.zip")
121
  with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as z:
122
  for item in manifest:
123
- fname = item.get("filename", JSON_FALLBACK_NAME).lstrip("/")
124
  content = item.get("content", "")
125
  fpath = os.path.join(temp_dir, fname)
126
  os.makedirs(os.path.dirname(fpath), exist_ok=True)
@@ -129,28 +119,12 @@ def create_zip_from_manifest(manifest):
129
  z.write(fpath, arcname=fname)
130
  return zip_path
131
 
132
- def package_with_llm(ai_text, repo_id, filename, temperature, top_p, top_k, repeat_penalty, max_tokens, force_heuristic):
133
- model_path = ensure_model(repo_id, filename)
134
- agent, provider = build_agent(model_path=model_path)
135
-
136
- manifest = call_llm_manifest(
137
- agent, provider, ai_text,
138
- temperature=temperature, top_p=top_p, top_k=top_k,
139
- repeat_penalty=repeat_penalty, max_tokens=max_tokens
140
- )
141
-
142
- # If model failed to JSON-ify properly (single fallback) or user forces merge, try heuristic merge
143
- if force_heuristic or (len(manifest) == 1 and manifest[0]["filename"] == JSON_FALLBACK_NAME):
144
- heuristic = naive_regex_merge(ai_text)
145
- if heuristic:
146
- manifest = heuristic
147
-
148
- zip_path = create_zip_from_manifest(manifest)
149
- return zip_path
150
-
151
- with gr.Blocks(title="AI Project Packager (GGUF, llama.cpp)") as demo:
152
- gr.Markdown("# AI Project Packager (GGUF, llama.cpp)")
153
- gr.Markdown("Paste an AI-generated multi-file project description. A local GGUF model will infer filenames and contents, then return a downloadable ZIP.")
154
 
155
  with gr.Row():
156
  ai_text = gr.Textbox(lines=24, label="Paste AI response here")
 
 
1
  import os
2
  import re
3
  import json
4
  import tempfile
5
  import zipfile
6
  import gradio as gr
7
+ import spaces
8
  from huggingface_hub import hf_hub_download
9
 
10
  # ---- LLM: llama.cpp via llama_cpp_agent ----
 
15
  # ----------------------
16
  # Model configuration
17
  # ----------------------
 
18
  DEFAULT_REPO_ID = "tHottie/NeuralDaredevil-8B-abliterated-Q4_K_M-GGUF"
19
  DEFAULT_FILENAME = "neuraldaredevil-8b-abliterated-q4_k_m-imat.gguf"
20
  MODELS_DIR = "models"
 
21
  os.makedirs(MODELS_DIR, exist_ok=True)
22
 
23
  def ensure_model(repo_id: str, filename: str) -> str:
 
26
  hf_hub_download(repo_id=repo_id, filename=filename, local_dir=MODELS_DIR)
27
  return local_path
28
 
29
+ # GPU context ensures model loads only when a GPU session is active
30
+ @spaces.GPU(duration=120)
31
+ def package_with_llm(ai_text, repo_id, filename, temperature, top_p, top_k, repeat_penalty, max_tokens, force_heuristic):
32
+ model_path = ensure_model(repo_id, filename)
33
  llm = Llama(
34
  model_path=model_path,
35
+ n_ctx=8192,
36
+ n_gpu_layers=81,
37
+ n_batch=1024,
38
+ flash_attn=True,
39
  )
40
  provider = LlamaCppPythonProvider(llm)
41
  agent = LlamaCppAgent(
 
53
  predefined_messages_formatter_type=MessagesFormatterType.GEMMA_2,
54
  debug_output=False
55
  )
 
56
 
 
 
 
 
 
57
  prompt = f"""
58
+ Read the following AI project description and return ONLY JSON.
59
  Output schema (strict):
60
  [{{"filename": "server.js", "content": "// code..."}}]
61
 
62
  AI project description:
63
+ {ai_text}
64
  """
65
+
66
  settings = provider.get_provider_default_settings()
67
  settings.temperature = float(temperature)
68
  settings.top_p = float(top_p)
 
72
  settings.stream = False
73
 
74
  out = agent.get_chat_response(prompt, llm_sampling_settings=settings, print_output=False)
75
+
76
+ # Parse JSON output robustly
77
  try:
78
+ start, end = out.find('['), out.rfind(']')
79
+ if start != -1 and end > start:
80
+ manifest = json.loads(out[start:end+1])
 
 
 
81
  else:
82
+ raise ValueError("No JSON found")
83
  except Exception:
84
+ manifest = [{"filename": "project.txt", "content": out}]
85
+
86
+ # Heuristic fallback if model fails
87
+ if force_heuristic or (len(manifest) == 1 and manifest[0]["filename"] == "project.txt"):
88
+ manifest = naive_regex_merge(ai_text)
89
+
90
+ return create_zip_from_manifest(manifest)
91
 
92
  def naive_regex_merge(text):
 
 
 
 
93
  blocks = []
 
94
  code_pattern = re.compile(r"```([a-zA-Z0-9]*)\n(.*?)```", re.DOTALL)
 
95
  lines = text.splitlines()
96
  candidates = []
97
+ for line in lines:
98
+ m = re.search(r"([A-Za-z0-9_\-./]+?\.[A-Za-z0-9]+)", line)
99
  if m:
100
  candidates.append(m.group(1))
 
101
  for idx, m in enumerate(code_pattern.finditer(text)):
102
  lang = m.group(1) or "txt"
103
  code = m.group(2)
 
110
  zip_path = os.path.join(temp_dir, "project.zip")
111
  with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as z:
112
  for item in manifest:
113
+ fname = item.get("filename", "project.txt").lstrip("/")
114
  content = item.get("content", "")
115
  fpath = os.path.join(temp_dir, fname)
116
  os.makedirs(os.path.dirname(fpath), exist_ok=True)
 
119
  z.write(fpath, arcname=fname)
120
  return zip_path
121
 
122
+ # --------------------------
123
+ # Gradio Interface
124
+ # --------------------------
125
+ with gr.Blocks(title="AI Project Packager (GGUF, ZeroGPU)") as demo:
126
+ gr.Markdown("# AI Project Packager (GGUF, ZeroGPU)")
127
+ gr.Markdown("Uses ephemeral GPU power to infer filenames & package AI-generated code projects.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
  with gr.Row():
130
  ai_text = gr.Textbox(lines=24, label="Paste AI response here")