Sávio Santos
commited on
Commit
·
b0fac8f
1
Parent(s):
f619222
Improviments
Browse files- README.md +1 -1
- app.py +17 -75
- requirements.txt +2 -1
- src/examples.py +2 -2
- src/interface.py +60 -0
- src/plantuml.py +1 -1
- src/{retriever_tool.py → retriever.py} +0 -0
- src/utils.py +14 -0
README.md
CHANGED
@@ -53,7 +53,7 @@ To set up and run the PlantUML Agent locally, follow these steps:
|
|
53 |
2. **Create a conda environment:**
|
54 |
|
55 |
```bash
|
56 |
-
conda create -n plantuml-agent python=3.
|
57 |
conda activate plantuml-agent
|
58 |
```
|
59 |
|
|
|
53 |
2. **Create a conda environment:**
|
54 |
|
55 |
```bash
|
56 |
+
conda create -n plantuml-agent python=3.12 --y
|
57 |
conda activate plantuml-agent
|
58 |
```
|
59 |
|
app.py
CHANGED
@@ -1,23 +1,21 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
from smolagents import InferenceClientModel, CodeAgent
|
3 |
from src.documents import get_processed_documents
|
4 |
-
from src.
|
5 |
from src.plantuml import render_plantuml
|
6 |
-
from src.
|
7 |
-
import
|
8 |
-
from dotenv import load_dotenv
|
9 |
-
import os
|
10 |
|
11 |
-
|
|
|
12 |
|
13 |
-
|
|
|
14 |
|
15 |
-
|
16 |
|
17 |
-
docs_processed = get_processed_documents(
|
18 |
retriever_tool = RetrieverTool(docs_processed)
|
19 |
|
20 |
-
model = InferenceClientModel('microsoft/phi-4', api_key=
|
21 |
|
22 |
agent = CodeAgent(
|
23 |
tools=[retriever_tool],
|
@@ -26,76 +24,20 @@ agent = CodeAgent(
|
|
26 |
verbosity_level=2,
|
27 |
)
|
28 |
|
|
|
29 |
def get_plantuml_diagram(message):
|
30 |
-
prompt = (
|
31 |
-
f"{message}\n"
|
32 |
-
"Use the PlantUML syntax and include all necessary components.\n"
|
33 |
-
"Return the PlantUML code wrapped in @startuml and @enduml tags.")
|
34 |
-
|
35 |
response = agent.run(prompt)
|
36 |
-
|
37 |
-
|
38 |
-
return f"@startuml\n{matches[0].strip()}\n@enduml"
|
39 |
-
return "@startuml\n@enduml"
|
40 |
|
41 |
def respond(message):
|
42 |
plantuml_code = get_plantuml_diagram(message)
|
43 |
svg_output = render_plantuml(plantuml_code)
|
44 |
return "", plantuml_code, svg_output
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
PLANTUML_EXAMPLES = get_plantuml_examples()
|
50 |
-
example_names = list(PLANTUML_EXAMPLES.keys())
|
51 |
-
|
52 |
-
with gr.Blocks(title="PlantUML Agent") as demo:
|
53 |
-
with gr.Row():
|
54 |
-
gr.HTML(
|
55 |
-
"""
|
56 |
-
<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
|
57 |
-
<img src="https://repository-images.githubusercontent.com/553868400/2f7375d8-c2ee-44fe-81d0-a8a29ec284da" alt="PlantUML Logo" style="height: 50px;">
|
58 |
-
<h1>PlantUML Agent</h1>
|
59 |
-
</div>
|
60 |
-
<p style="font-size: 1.2em;">Generate UML diagrams using <a href="https://plantuml.com" target="_blank">PlantUML</a> syntax with the help of an AI agent.</p>
|
61 |
-
<p style="font-size: 0.9em;">Diagrams supported: Sequence, Use Case, Class, Object, Activity, Component, Deployment, State, and Timing.</p>
|
62 |
-
"""
|
63 |
-
)
|
64 |
|
65 |
-
with gr.Row():
|
66 |
-
with gr.Column(scale=1):
|
67 |
-
gr.Markdown("### Input")
|
68 |
-
msg = gr.Textbox(label="Type your PlantUML description here...", placeholder="e.g., create a basic use case class", lines=3)
|
69 |
-
gr.Markdown("### Examples:")
|
70 |
-
example_dropdown = gr.Dropdown(
|
71 |
-
choices=example_names,
|
72 |
-
label="Choose a diagram description example",
|
73 |
-
interactive=True
|
74 |
-
)
|
75 |
-
|
76 |
-
example_dropdown.change(
|
77 |
-
fn=set_example_input,
|
78 |
-
inputs=example_dropdown,
|
79 |
-
outputs=msg
|
80 |
-
)
|
81 |
-
|
82 |
-
submit = gr.Button("Generate Diagram")
|
83 |
-
|
84 |
-
|
85 |
-
with gr.Row():
|
86 |
-
with gr.Column(scale=1):
|
87 |
-
gr.Markdown("### PlantUML Code")
|
88 |
-
diagram_text_output = gr.Code(label="", lines=15, interactive=False)
|
89 |
-
with gr.Column(scale=1):
|
90 |
-
gr.Markdown("### PlantUML Preview")
|
91 |
-
diagram_output = gr.HTML(label="")
|
92 |
-
|
93 |
-
with gr.Row():
|
94 |
-
gr.Markdown(
|
95 |
-
"Powered by SmolAgents, Phi-4, BM25Retriever, LangChain, Gradio, and PlantUML."
|
96 |
-
)
|
97 |
-
|
98 |
-
submit.click(respond, [msg], [msg, diagram_text_output, diagram_output])
|
99 |
-
msg.submit(respond, [msg], [msg, diagram_text_output, diagram_output])
|
100 |
-
|
101 |
demo.launch()
|
|
|
|
|
|
|
1 |
from src.documents import get_processed_documents
|
2 |
+
from src.retriever import RetrieverTool
|
3 |
from src.plantuml import render_plantuml
|
4 |
+
from src.utils import get_prompt, get_processed_response
|
5 |
+
from src.interface import create_interface
|
|
|
|
|
6 |
|
7 |
+
from smolagents import InferenceClientModel, CodeAgent
|
8 |
+
from cachetools import LRUCache, cached
|
9 |
|
10 |
+
import os
|
11 |
+
from dotenv import load_dotenv
|
12 |
|
13 |
+
load_dotenv()
|
14 |
|
15 |
+
docs_processed = get_processed_documents("PlantUML_Language_Reference_Guide_en.pdf")
|
16 |
retriever_tool = RetrieverTool(docs_processed)
|
17 |
|
18 |
+
model = InferenceClientModel('microsoft/phi-4', api_key=os.getenv("HF_TOKEN"))
|
19 |
|
20 |
agent = CodeAgent(
|
21 |
tools=[retriever_tool],
|
|
|
24 |
verbosity_level=2,
|
25 |
)
|
26 |
|
27 |
+
@cached(LRUCache(maxsize=100))
|
28 |
def get_plantuml_diagram(message):
|
29 |
+
prompt = get_prompt(message)
|
|
|
|
|
|
|
|
|
30 |
response = agent.run(prompt)
|
31 |
+
|
32 |
+
return get_processed_response(response)
|
|
|
|
|
33 |
|
34 |
def respond(message):
|
35 |
plantuml_code = get_plantuml_diagram(message)
|
36 |
svg_output = render_plantuml(plantuml_code)
|
37 |
return "", plantuml_code, svg_output
|
38 |
|
39 |
+
if __name__ == "__main__":
|
40 |
+
demo = create_interface(respond)
|
41 |
+
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
demo.launch()
|
requirements.txt
CHANGED
@@ -7,4 +7,5 @@ smolagents[gradio]
|
|
7 |
plantweb
|
8 |
rank_bm25
|
9 |
numpy==1.26.4
|
10 |
-
python-dotenv
|
|
|
|
7 |
plantweb
|
8 |
rank_bm25
|
9 |
numpy==1.26.4
|
10 |
+
python-dotenv
|
11 |
+
cachetools
|
src/examples.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
def get_plantuml_examples():
|
2 |
return {
|
3 |
-
'
|
4 |
"description": "Select a diagram type to see examples.",
|
5 |
-
"input": ""
|
6 |
},
|
7 |
"Use Case Diagram": {
|
8 |
"description": "A use case diagram showing how users (actors) interact with a system and what functionalities (use cases) they use.",
|
|
|
1 |
def get_plantuml_examples():
|
2 |
return {
|
3 |
+
'Default example': {
|
4 |
"description": "Select a diagram type to see examples.",
|
5 |
+
"input": "Generate a simple use case diagram."
|
6 |
},
|
7 |
"Use Case Diagram": {
|
8 |
"description": "A use case diagram showing how users (actors) interact with a system and what functionalities (use cases) they use.",
|
src/interface.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from src.examples import get_plantuml_examples
|
3 |
+
|
4 |
+
def create_interface(respond):
|
5 |
+
PLANTUML_EXAMPLES = get_plantuml_examples()
|
6 |
+
example_names = list(PLANTUML_EXAMPLES.keys())
|
7 |
+
|
8 |
+
def set_example_input(example_name):
|
9 |
+
return PLANTUML_EXAMPLES.get(example_name, "")
|
10 |
+
|
11 |
+
with gr.Blocks(title="PlantUML Agent") as demo:
|
12 |
+
with gr.Row():
|
13 |
+
gr.HTML(
|
14 |
+
"""
|
15 |
+
<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
|
16 |
+
<img src="https://repository-images.githubusercontent.com/553868400/2f7375d8-c2ee-44fe-81d0-a8a29ec284da" alt="PlantUML Logo" style="height: 50px;">
|
17 |
+
<h1>PlantUML Agent</h1>
|
18 |
+
</div>
|
19 |
+
<p style="font-size: 1.2em;">Generate UML diagrams using <a href="https://plantuml.com" target="_blank">PlantUML</a> syntax with the help of an AI agent.</p>
|
20 |
+
<p style="font-size: 0.9em;">Diagrams supported: Sequence, Use Case, Class, Object, Activity, Component, Deployment, State, and Timing.</p>
|
21 |
+
"""
|
22 |
+
)
|
23 |
+
|
24 |
+
with gr.Row():
|
25 |
+
with gr.Column(scale=1):
|
26 |
+
gr.Markdown("### Input")
|
27 |
+
msg = gr.Textbox(label="Type your PlantUML description here...", placeholder="e.g., create a basic use case class", lines=3)
|
28 |
+
gr.Markdown("### Examples:")
|
29 |
+
example_dropdown = gr.Dropdown(
|
30 |
+
choices=example_names,
|
31 |
+
label="Choose a diagram description example",
|
32 |
+
interactive=True
|
33 |
+
)
|
34 |
+
|
35 |
+
example_dropdown.change(
|
36 |
+
fn=set_example_input,
|
37 |
+
inputs=example_dropdown,
|
38 |
+
outputs=msg
|
39 |
+
)
|
40 |
+
|
41 |
+
submit = gr.Button("Generate Diagram")
|
42 |
+
|
43 |
+
|
44 |
+
with gr.Row():
|
45 |
+
with gr.Column(scale=1):
|
46 |
+
gr.Markdown("### PlantUML Code")
|
47 |
+
diagram_text_output = gr.Code(label="", lines=15, interactive=False)
|
48 |
+
with gr.Column(scale=1):
|
49 |
+
gr.Markdown("### PlantUML Preview")
|
50 |
+
diagram_output = gr.HTML(label="")
|
51 |
+
|
52 |
+
with gr.Row():
|
53 |
+
gr.Markdown(
|
54 |
+
"Powered by SmolAgents, Phi-4, BM25Retriever, LangChain, LRUCache, Gradio, and PlantUML."
|
55 |
+
)
|
56 |
+
|
57 |
+
submit.click(respond, [msg], [msg, diagram_text_output, diagram_output])
|
58 |
+
msg.submit(respond, [msg], [msg, diagram_text_output, diagram_output])
|
59 |
+
|
60 |
+
return demo
|
src/plantuml.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
from plantweb import render
|
2 |
|
3 |
def render_plantuml(uml_code):
|
4 |
-
svg_output = render.render(uml_code, engine='plantuml', format='svg')
|
5 |
return svg_output
|
|
|
1 |
from plantweb import render
|
2 |
|
3 |
def render_plantuml(uml_code):
|
4 |
+
svg_output, _, _, _ = render.render(uml_code, engine='plantuml', format='svg')
|
5 |
return svg_output
|
src/{retriever_tool.py → retriever.py}
RENAMED
File without changes
|
src/utils.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
|
3 |
+
def get_prompt(message):
|
4 |
+
return ("Generate a PlantUML diagram based on the following message:\n"
|
5 |
+
f"{message}\n"
|
6 |
+
"Use the PlantUML syntax and include all necessary components.\n"
|
7 |
+
"Return the PlantUML code wrapped in @startuml and @enduml tags."
|
8 |
+
"Do not include any additional text outside these tags without commenting it out.")
|
9 |
+
|
10 |
+
def get_processed_response(response):
|
11 |
+
matches = re.findall(r"@startuml(.*?)@enduml", response, re.DOTALL)
|
12 |
+
if matches:
|
13 |
+
return f"@startuml\n{matches[0].strip()}\n@enduml"
|
14 |
+
return "@startuml\n@enduml"
|