Skip to content

Commit 1ba0e75

Browse files
authored
Merge pull request #43 from minitap-ai/TASK-173/automatic-langgraph-graph-documentation
feat(docs): Implement automatic graph documentation generation
2 parents d046ba1 + 1655f5c commit 1ba0e75

File tree

5 files changed

+158
-0
lines changed

5 files changed

+158
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Update Graph Documentation 🦜📚
2+
on:
3+
pull_request:
4+
types: [opened, synchronize]
5+
branches: [main]
6+
paths:
7+
- "minitap/mobile_use/graph/graph.py"
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
update-docs:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v5
19+
with:
20+
token: ${{ secrets.GITHUB_TOKEN }}
21+
fetch-depth: 0
22+
ref: ${{ github.head_ref }}
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: "3.12"
28+
29+
- name: Install system dependencies
30+
run: |
31+
sudo apt-get update
32+
sudo apt-get install -y graphviz graphviz-dev
33+
34+
- name: Install uv
35+
uses: astral-sh/setup-uv@v6
36+
with:
37+
enable-cache: true
38+
39+
- name: Install dependencies
40+
run: |
41+
uv sync
42+
43+
- name: Generate graph documentation
44+
run: uv run python scripts/doc/generate_graph_docs.py
45+
46+
- name: Check for changes
47+
id: changes
48+
run: |
49+
git add doc/graph.png
50+
if git diff --cached --quiet doc/graph.png; then
51+
echo "changed=false" >> $GITHUB_OUTPUT
52+
else
53+
echo "changed=true" >> $GITHUB_OUTPUT
54+
fi
55+
56+
- name: Get last commit author
57+
if: steps.changes.outputs.changed == 'true'
58+
id: author
59+
run: |
60+
echo "name=$(git log -1 --pretty=format:'%an')" >> $GITHUB_OUTPUT
61+
echo "email=$(git log -1 --pretty=format:'%ae')" >> $GITHUB_OUTPUT
62+
63+
- name: Commit and push changes
64+
if: steps.changes.outputs.changed == 'true'
65+
run: |
66+
git config --local user.email "${{ steps.author.outputs.email }}"
67+
git config --local user.name "${{ steps.author.outputs.name }}"
68+
git add doc/graph.png
69+
git commit -m "chore(doc): Update graph documentation [skip ci]"
70+
git push

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ python ./src/mobile_use/main.py \
204204
> [!NOTE]
205205
> If you haven't configured a specific model, mobile-use will prompt you to choose one from the available options.
206206

207+
## 🔎 Agentic System Overview
208+
209+
<div align="center">
210+
211+
![Graph Visualization](doc/graph.png)
212+
213+
_This diagram is automatically updated from the codebase. This is our current agentic system architecture._
214+
215+
</div>
216+
207217
## ❤️ Contributing
208218

209219
We love contributions! Whether you're fixing a bug, adding a feature, or improving documentation, your help is welcome. Please read our **[Contributing Guidelines](CONTRIBUTING.md)** to get started.

doc/graph.png

45.8 KB
Loading

minitap/mobile_use/graph/graph.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from langgraph.constants import END, START
77
from langgraph.graph import StateGraph
88
from langgraph.graph.state import CompiledStateGraph
9+
910
from minitap.mobile_use.agents.contextor.contextor import ContextorNode
1011
from minitap.mobile_use.agents.cortex.cortex import CortexNode
1112
from minitap.mobile_use.agents.executor.executor import ExecutorNode

scripts/doc/generate_graph_docs.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate graph visualization from the LangGraph structure.
4+
This creates both a PNG image and a Mermaid markdown file.
5+
It updates the README.md file with the generated graph.
6+
"""
7+
8+
import asyncio
9+
import sys
10+
from pathlib import Path
11+
12+
from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles
13+
from langchain_core.runnables.graph_mermaid import draw_mermaid_png
14+
from langgraph.graph.state import CompiledStateGraph
15+
16+
from minitap.mobile_use.clients.device_hardware_client import DeviceHardwareClient
17+
from minitap.mobile_use.clients.screen_api_client import ScreenApiClient
18+
from minitap.mobile_use.config import get_default_llm_config
19+
from minitap.mobile_use.context import (
20+
DeviceContext,
21+
DevicePlatform,
22+
)
23+
24+
sys.path.append(str(Path(__file__).parent.parent))
25+
26+
27+
async def generate_graph_docs():
28+
"""Generate graph visualization as PNG."""
29+
from minitap.mobile_use.context import MobileUseContext
30+
from minitap.mobile_use.graph.graph import get_graph
31+
32+
print("Loading graph structure...")
33+
ctx = MobileUseContext(
34+
device=DeviceContext(
35+
host_platform="LINUX",
36+
mobile_platform=DevicePlatform.ANDROID,
37+
device_id="device_id",
38+
device_width=1080,
39+
device_height=1920,
40+
),
41+
hw_bridge_client=DeviceHardwareClient(base_url="http://localhost:8000"),
42+
screen_api_client=ScreenApiClient(base_url="http://localhost:8000"),
43+
llm_config=get_default_llm_config(),
44+
)
45+
46+
print("Generating graph...")
47+
graph: CompiledStateGraph = await get_graph(ctx)
48+
49+
png_path = Path(__file__).parent.parent.parent / "doc" / "graph.png"
50+
print(f"Generating PNG at {png_path}...")
51+
52+
mermaid_text = graph.get_graph().draw_mermaid(
53+
node_colors=NodeStyles(
54+
default="fill:#d0c4f2,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
55+
first="fill:#9998e1,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
56+
last="fill:#9998e1,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
57+
),
58+
curve_style=CurveStyle.LINEAR,
59+
frontmatter_config={
60+
"config": {
61+
"themeVariables": {
62+
"lineColor": "#ffffff",
63+
},
64+
}
65+
},
66+
)
67+
68+
draw_mermaid_png(
69+
mermaid_syntax=mermaid_text,
70+
output_file_path=str(png_path),
71+
draw_method=MermaidDrawMethod.API,
72+
background_color=None,
73+
)
74+
75+
76+
if __name__ == "__main__":
77+
asyncio.run(generate_graph_docs())

0 commit comments

Comments
 (0)