Added a diagram generator (based on my drawittome tool)
Browse files- .gitignore +1 -0
- app.py +5 -3
- requirements.txt +5 -1
- tools/diagrams.py +93 -0
.gitignore
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
.env
|
|
|
2 |
# Byte-compiled / optimized / DLL files
|
3 |
__pycache__/
|
4 |
*.py[cod]
|
|
|
1 |
.env
|
2 |
+
tests/
|
3 |
# Byte-compiled / optimized / DLL files
|
4 |
__pycache__/
|
5 |
*.py[cod]
|
app.py
CHANGED
@@ -1,17 +1,19 @@
|
|
1 |
import gradio as gr
|
2 |
-
from tools import jokes, weather, datasetananalysis
|
3 |
|
4 |
|
5 |
demo = gr.TabbedInterface(
|
6 |
[
|
7 |
gr.Interface(fn=jokes.smalljoke,inputs=["text"],outputs="text", title="Small joke teller", description="Tells a small joke in french"),
|
8 |
gr.Interface(fn=jokes.longjoke,inputs=["text","text","text","text" ],outputs="text", title="Long joke teller", description="Tells a longer joke in french"),
|
9 |
-
gr.Interface(fn=datasetananalysis.describedataset,inputs=["text" ],outputs="text", title="Dataset descriptor", description="Provides a usefull description of a dataset to allow content and structure awareness before SQL requesting on it.")
|
|
|
10 |
],
|
11 |
[
|
12 |
"Histoire courte",
|
13 |
"Histoire longue",
|
14 |
-
"Description d'un dataset"
|
|
|
15 |
]
|
16 |
)
|
17 |
|
|
|
1 |
import gradio as gr
|
2 |
+
from tools import jokes, weather, datasetananalysis, diagrams
|
3 |
|
4 |
|
5 |
demo = gr.TabbedInterface(
|
6 |
[
|
7 |
gr.Interface(fn=jokes.smalljoke,inputs=["text"],outputs="text", title="Small joke teller", description="Tells a small joke in french"),
|
8 |
gr.Interface(fn=jokes.longjoke,inputs=["text","text","text","text" ],outputs="text", title="Long joke teller", description="Tells a longer joke in french"),
|
9 |
+
gr.Interface(fn=datasetananalysis.describedataset,inputs=["text" ],outputs="text", title="Dataset descriptor", description="Provides a usefull description of a dataset to allow content and structure awareness before SQL requesting on it."),
|
10 |
+
gr.Interface(fn=diagrams.generateDiagram, inputs=["text","text"], outputs=["html","html","text","text"], title="Diagrams generator", description="Generates a mermaid diagram to explain a submited text. The diagram is returned in different formats(svg and raw code)")
|
11 |
],
|
12 |
[
|
13 |
"Histoire courte",
|
14 |
"Histoire longue",
|
15 |
+
"Description d'un dataset",
|
16 |
+
"Générateur de diagrammes"
|
17 |
]
|
18 |
)
|
19 |
|
requirements.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1 |
python-dotenv
|
2 |
gradio[mcp]
|
3 |
-
openai
|
|
|
|
|
|
|
|
|
|
1 |
python-dotenv
|
2 |
gradio[mcp]
|
3 |
+
openai
|
4 |
+
huggingface_hub
|
5 |
+
zlib
|
6 |
+
base64
|
7 |
+
huggingface_hub
|
tools/diagrams.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import zlib
|
2 |
+
import base64
|
3 |
+
import os
|
4 |
+
from dotenv import load_dotenv
|
5 |
+
from huggingface_hub import InferenceClient
|
6 |
+
|
7 |
+
load_dotenv()
|
8 |
+
os.environ["SAMBANOVA_API_KEY"]
|
9 |
+
|
10 |
+
PROMPT="""
|
11 |
+
###PERSONA : Tu es un analyste métier sénior, expert en vulgarisation et en diagrammes formels.
|
12 |
+
###INSTRUCTION : En fonction d’un sujet donné, sélectionne le type de diagramme le plus adapté parmi ceux listés, puis génère un diagramme complet, lisible, et détaillé. Syntaxe Mermaid uniquement, sans explication hors-code.
|
13 |
+
Génère le code mermaid, et rien que le code mermaid expliquant le mieux la description qui suit.
|
14 |
+
### Sélection du type de diagramme (`mermaid_diag_type`) :
|
15 |
+
- `Graph TB` : **choix par défaut**. Regroupe les éléments par blocs. Applique des couleurs si possible.
|
16 |
+
- `flowchart TD` : pour les **processus** et **arbres de décision**.
|
17 |
+
- `sequenceDiagram` : pour les **enchaînements complexes** entre **acteurs ou systèmes**.
|
18 |
+
- `classDiagram` : si **demande explicite** ou si **entrants techniques** (ex. schéma SQL).
|
19 |
+
- `stateDiagram-v2` : si **demande explicite** ou **entrants techniques** comme une user story.
|
20 |
+
- `erDiagram` : autre **choix par défaut** pour exposer les relations entités-attributs. Regroupe et colore les blocs.
|
21 |
+
- `gantt` : si **thématique projet ou travaux**, avec des **tâches identifiables**.
|
22 |
+
- `timeline` : pour toute **chronologie**, **biographie**, ou **historique**. Regroupe les événements par **décennie**, ou **siècle** si nécessaire. Exemple de syntaxe :
|
23 |
+
timeline
|
24 |
+
title History of Social Media Platform
|
25 |
+
2002 : LinkedIn
|
26 |
+
2004 : Facebook
|
27 |
+
: Google
|
28 |
+
2005 : YouTube
|
29 |
+
2006 : Twitter
|
30 |
+
|
31 |
+
### Règles de syntaxe :
|
32 |
+
- Les noms d’entités doivent être **concis**.
|
33 |
+
- Ne pas utiliser de **parenthèses** sauf si **sens sémantique clair** : elles perturbent le parsing Mermaid.
|
34 |
+
- Évite aussi les caractères spéciaux non compatibles Mermaid (`@`, `{}`, `[]`, etc.).
|
35 |
+
- Utilise des noms explicites pour les nœuds (ex. `AgentDemandeur` plutôt que `A`)
|
36 |
+
- Utilise `%%` pour commenter ou annoter hors rendu visuel.
|
37 |
+
- Segmente clairement, évite les diagrammes illisibles ou trop denses.
|
38 |
+
- Rédige dans la **langue du demandeur** ou celle du **texte d’origine**.
|
39 |
+
|
40 |
+
Objectif : produire un diagramme Mermaid clair, fidèle, et directement exploitable dans un contexte explicatif, technique ou décisionnel.
|
41 |
+
"""
|
42 |
+
import os
|
43 |
+
|
44 |
+
|
45 |
+
|
46 |
+
def getModelResponseFromContent(content, provider_name="sambanova", provider_env_key="SAMBANOVA_API_KEY", model="meta-llama/Llama-4-Scout-17B-16E-Instruct"):
|
47 |
+
client = InferenceClient(
|
48 |
+
provider=provider_name,
|
49 |
+
api_key=os.environ[provider_env_key],
|
50 |
+
)
|
51 |
+
|
52 |
+
completion = client.chat.completions.create(
|
53 |
+
model=model,
|
54 |
+
messages=[
|
55 |
+
{
|
56 |
+
"role": "user",
|
57 |
+
f"content": content
|
58 |
+
}
|
59 |
+
],
|
60 |
+
)
|
61 |
+
|
62 |
+
raw_response = completion.choices[0].message.content
|
63 |
+
mermaid_code_cleaned = raw_response.replace("```mermaid", "").replace("```", "").strip()
|
64 |
+
mermaid_diagram_type = mermaid_code_cleaned.split('\n', 1)[0].strip()
|
65 |
+
|
66 |
+
return mermaid_code_cleaned, mermaid_diagram_type
|
67 |
+
|
68 |
+
def kroki_img_from_mermaid(mermaid_code: str, output_format: str = "svg") -> str:
|
69 |
+
compressed = zlib.compress(mermaid_code.encode('utf-8'))
|
70 |
+
b64 = base64.urlsafe_b64encode(compressed).decode('utf-8')
|
71 |
+
image_url = f"https://kroki.io/mermaid/{output_format}/{b64}"
|
72 |
+
html_img = f"""<a href="{image_url}" target="_blank"> <img src="{image_url}" alt="Diagramme Mermaid via Kroki" > </a>"""
|
73 |
+
return html_img
|
74 |
+
|
75 |
+
|
76 |
+
def generateDiagram(input_text="I broke my car yesterday, and the mechanics will give it back to me after insurance payment.", input_precisions="Choose the best diagram paradigm"):
|
77 |
+
"""Generates a mermaid diagram to explain a submited text. The diagram is returned in different formats(html and raw code)
|
78 |
+
|
79 |
+
Args:
|
80 |
+
input_text: the text to explain with a diagram.
|
81 |
+
input_precisions: diagram settings, by default the tool has the ability to choose the best type of diagram.
|
82 |
+
|
83 |
+
Returns:
|
84 |
+
kroki_html_img: svg image in an img html tag.
|
85 |
+
kroki_html_link: full kroki link with image and link to kroki page.
|
86 |
+
mermaid_diag_type: type of diagram selected by the tool
|
87 |
+
mermaid_code: mermaid code
|
88 |
+
"""
|
89 |
+
full_content_prompt = f"{PROMPT}. ###INPUT : {input_text}. ###PRECISIONS {input_precisions}"
|
90 |
+
mermaid_code, mermaid_diag_type = getModelResponseFromContent(content=full_content_prompt )
|
91 |
+
kroki_html_link = kroki_img_from_mermaid(mermaid_code)
|
92 |
+
kroki_html_img = kroki_html_link[kroki_html_link.find('<img '):kroki_html_link.find('>', kroki_html_link.find('<img ')) + 1]
|
93 |
+
return kroki_html_img, kroki_html_link, mermaid_diag_type, mermaid_code
|