slenk commited on
Commit
e26444e
·
verified ·
1 Parent(s): 690854e

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +93 -8
app.py CHANGED
@@ -15,7 +15,7 @@ from typing import Any
15
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
16
 
17
  # Force pandas to fully initialize before transitive imports cause circular import
18
- import pandas # noqa: F401
19
 
20
  import gradio as gr
21
  import spaces
@@ -192,7 +192,8 @@ def generate_spec(
192
  )
193
 
194
  generated = outputs[0][input_len:]
195
- return tokenizer.decode(generated, skip_special_tokens=True)
 
196
 
197
  except Exception as e:
198
  return (
@@ -204,28 +205,112 @@ def generate_spec(
204
  # --- Gradio UI ---
205
 
206
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  def create_app():
208
  mermaid_css = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  .mermaid .node rect,
210
  .mermaid .node polygon,
211
  .mermaid .node circle {
212
  fill: #e8f0fe !important;
213
  stroke: #4a6fa5 !important;
214
  }
215
- .mermaid .nodeLabel,
216
- .mermaid .edgeLabel,
217
- .mermaid text {
218
- color: #1a1a1a !important;
219
- fill: #1a1a1a !important;
220
- }
221
  .mermaid .edgePath .path {
222
  stroke: #4a6fa5 !important;
223
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  """
225
 
226
  with gr.Blocks(
227
  title="CodeWraith - Module-to-Spec Transformer",
228
  css=mermaid_css,
 
229
  ) as app:
230
  gr.Markdown(
231
  "# CodeWraith\n"
 
15
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
16
 
17
  # Force pandas to fully initialize before transitive imports cause circular import
18
+ import pandas # noqa: F401, I001
19
 
20
  import gradio as gr
21
  import spaces
 
192
  )
193
 
194
  generated = outputs[0][input_len:]
195
+ spec = tokenizer.decode(generated, skip_special_tokens=True)
196
+ return render_mermaid_images(spec)
197
 
198
  except Exception as e:
199
  return (
 
205
  # --- Gradio UI ---
206
 
207
 
208
+ def render_mermaid_images(spec: str) -> str:
209
+ """Replace mermaid code blocks with rendered SVG images via mermaid.ink.
210
+
211
+ Validates the mermaid syntax first, strips malformed blocks, and
212
+ converts valid ones to inline images that render reliably regardless
213
+ of CSS/theme issues.
214
+ """
215
+ import base64
216
+ import re
217
+
218
+ valid_starts = (
219
+ "graph ",
220
+ "graph\n",
221
+ "flowchart ",
222
+ "flowchart\n",
223
+ "classDiagram",
224
+ "sequenceDiagram",
225
+ "stateDiagram",
226
+ "erDiagram",
227
+ "gantt",
228
+ "pie",
229
+ "gitgraph",
230
+ )
231
+
232
+ def replace_block(match: re.Match) -> str:
233
+ block = match.group(1).strip()
234
+ # Must start with a valid diagram type
235
+ if not any(block.startswith(s) for s in valid_starts):
236
+ return "*[Mermaid diagram removed: unrecognized diagram type]*"
237
+ # Check balanced brackets/braces
238
+ if block.count("[") != block.count("]"):
239
+ return "*[Mermaid diagram removed: unbalanced brackets]*"
240
+ if block.count("{") != block.count("}"):
241
+ return "*[Mermaid diagram removed: unbalanced braces]*"
242
+ if block.count("(") != block.count(")"):
243
+ return "*[Mermaid diagram removed: unbalanced parentheses]*"
244
+ # Encode and return as mermaid.ink image
245
+ encoded = base64.urlsafe_b64encode(block.encode("utf-8")).decode("ascii")
246
+ return f"![Dependency Diagram](https://mermaid.ink/svg/{encoded})"
247
+
248
+ return re.sub(r"```mermaid\s*\n(.*?)```", replace_block, spec, flags=re.DOTALL)
249
+
250
+
251
  def create_app():
252
  mermaid_css = """
253
+ /* Aggressive mermaid text fix — target all SVG text elements */
254
+ svg[id^="mermaid"] text,
255
+ svg[id^="mermaid"] tspan,
256
+ svg[id^="mermaid"] .nodeLabel,
257
+ svg[id^="mermaid"] .edgeLabel,
258
+ svg[id^="mermaid"] .label,
259
+ svg[id^="mermaid"] .cluster-label,
260
+ .mermaid text,
261
+ .mermaid tspan,
262
+ .mermaid .nodeLabel,
263
+ .mermaid .edgeLabel,
264
+ .mermaid .label,
265
+ [data-mermaid] text,
266
+ [data-mermaid] tspan {
267
+ color: #1a1a1a !important;
268
+ fill: #1a1a1a !important;
269
+ }
270
+ svg[id^="mermaid"] .node rect,
271
+ svg[id^="mermaid"] .node polygon,
272
+ svg[id^="mermaid"] .node circle,
273
  .mermaid .node rect,
274
  .mermaid .node polygon,
275
  .mermaid .node circle {
276
  fill: #e8f0fe !important;
277
  stroke: #4a6fa5 !important;
278
  }
279
+ svg[id^="mermaid"] .edgePath .path,
 
 
 
 
 
280
  .mermaid .edgePath .path {
281
  stroke: #4a6fa5 !important;
282
  }
283
+ svg[id^="mermaid"] .cluster rect,
284
+ .mermaid .cluster rect {
285
+ fill: #f0f4ff !important;
286
+ stroke: #4a6fa5 !important;
287
+ }
288
+ """
289
+
290
+ mermaid_js = """
291
+ () => {
292
+ if (window.mermaid) {
293
+ window.mermaid.initialize({
294
+ theme: 'default',
295
+ themeVariables: {
296
+ primaryColor: '#e8f0fe',
297
+ primaryTextColor: '#1a1a1a',
298
+ primaryBorderColor: '#4a6fa5',
299
+ lineColor: '#4a6fa5',
300
+ secondaryColor: '#f0f4ff',
301
+ tertiaryColor: '#fff',
302
+ nodeTextColor: '#1a1a1a',
303
+ edgeLabelBackground: '#ffffff',
304
+ }
305
+ });
306
+ }
307
+ }
308
  """
309
 
310
  with gr.Blocks(
311
  title="CodeWraith - Module-to-Spec Transformer",
312
  css=mermaid_css,
313
+ js=mermaid_js,
314
  ) as app:
315
  gr.Markdown(
316
  "# CodeWraith\n"