"""
3. Graph. Capture the resulting mermaid string and visualize it
To do
- create the custom gradio look
"""
from huggingface_hub import hf_hub_download
from llama_cpp import Llama
import gradio as gr
from gradio import Server
from fastapi.responses import HTMLResponse # serve the custom frontend from a route
from typing import Any, cast # to resolve PyLance freaking out over llama-cpp-python in the generate_flowchart function
from textwrap import dedent
import re # remove thinking tag from response
# ----- Get Model ----- #
# Download Q4_K_M GGUF file from the repo
model_path = hf_hub_download(
repo_id="Qwen/Qwen2.5-Coder-7B-Instruct-GGUF",
filename="qwen2.5-coder-7b-instruct-q4_k_m.gguf"
)
# Initialize llama.cpp with the local cached path
llm = Llama(
model_path=model_path,
n_ctx=2048,
n_threads=2
)
# ----- Init App ----- #
app = gr.Server(title="Code-to-Flowchart Generator")
# ----- Functions ----- #
@app.api(name="generate_flowchart")
def generate_flowchart(src_code: str) -> str:
# check if src_code is empty
if not src_code.strip(): return ""
# Set system prompt
system_prompt = dedent("""
## Role/Persona
You are a senior staff software architect and compiler engineer specializing in visual control-flow mapping. Your philosophy is pure utility: you translate raw execution logic into highly accurate, scannable, structural diagrams without any conversational filler, meta-commentary, or stylistic fluff.
## Context/Objective
The user will provide source code files or logic snippets. Your sole objective is to parse the syntax and output a corresponding, valid Mermaid.js flowchart graph. This graph will be rendered natively in a production UI to help developers audit execution paths at a glance.
## Strict Constraints
1. OUTPUT FORMAT: Output ONLY valid, raw Mermaid.js syntax.
2. NO MARKDOWN FENCING: Do not wrap the output in ```mermaid or ``` blocks. Start directly with the Mermaid graph definition, for example: graph TD.
3. NO PROSE: Do not include introductory text, explanations, or concluding remarks. If the code cannot be parsed, output an isolated error node.
4. NODE NAMING: Keep text inside the flowchart nodes descriptive but concise, under 5 words.
- Here is the flowchart
- ```mermaid
- ```
- Note:
- Explanation:
- In this diagram
- As requested
## Response Workflow
Before outputting the final diagram syntax, perform structural parsing inside a hidden tag according to these steps:
1. Identify all conditional branches, including if/else, loops, including for/while, and termination points, including return/throw.
2. Map out the execution flow nodes chronologically.
3. Verify that every opening bracket and node label matching syntax, including [ ], ( ), and { }, is perfectly balanced and closed according to Mermaid specifications.
4. Ensure no markdown formatting tags leak past the closing tag.
## Few-Shot Examples
Input:
def check_status(val):
if val > 10:
return "Active"
else:
return "Inactive"
Output:
1. Control structures: One conditional check, two return branches.
2. Nodes: A Start, B Conditional, C Active return, D Inactive return.
3. Syntax verification: B uses curly braces for decisions. Edges use standard arrows.
graph TD
A[Start: check_status] --> B{val > 10}
B -- True --> C[Return 'Active']
B -- False --> D[Return 'Inactive']
""").strip()
# Casting else PyLance gets mad
response = cast(Any, llm.create_chat_completion(
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": src_code}
],
temperature=0.1, # Keep it quite deterministic for now
max_tokens=1024,
stream=False
))
content = response["choices"][0]["message"]["content"]
# remove the thinking tags from the response
cleaned = re.sub(r'.*?', '', content, flags=re.DOTALL)
# Mermaid can't parse double quotes inside [node labels] (e.g. C[Return "Active"]);
# source-code string literals leak them, so downgrade to single quotes which parse fine.
cleaned = cleaned.replace('"', "'")
return cleaned.strip() # and remove excess whitespace
# ----- Custom Frontend ----- #
index_html = """
Code-to-Flowchart Generator
Flowchart Transpiler
Source Code Input
Mermaid Flowchart Visualizer
graph TD
A[Paste Code] --> B[Click Generate]
"""
# Load the custom HTML
# / takes precedent over default Blocks UI
@app.get("/")
def index():
return HTMLResponse(index_html)
app.launch(share=True)