Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/update-graph-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Update Graph Documentation πŸ¦œπŸ“š
on:
pull_request:
types: [opened, synchronize]
branches: [main]
paths:
- "minitap/mobile_use/graph/graph.py"
workflow_dispatch:

permissions:
contents: write

jobs:
update-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
ref: ${{ github.head_ref }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y graphviz graphviz-dev

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true

- name: Install dependencies
run: |
uv sync

- name: Generate graph documentation
run: uv run python scripts/doc/generate_graph_docs.py

- name: Check for changes
id: changes
run: |
git add doc/graph.png
if git diff --cached --quiet doc/graph.png; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi

- name: Get last commit author
if: steps.changes.outputs.changed == 'true'
id: author
run: |
echo "name=$(git log -1 --pretty=format:'%an')" >> $GITHUB_OUTPUT
echo "email=$(git log -1 --pretty=format:'%ae')" >> $GITHUB_OUTPUT

- name: Commit and push changes
if: steps.changes.outputs.changed == 'true'
run: |
git config --local user.email "${{ steps.author.outputs.email }}"
git config --local user.name "${{ steps.author.outputs.name }}"
git add doc/graph.png
git commit -m "chore(doc): Update graph documentation [skip ci]"
git push
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ python ./src/mobile_use/main.py \
> [!NOTE]
> If you haven't configured a specific model, mobile-use will prompt you to choose one from the available options.

## πŸ”Ž Agentic System Overview

<div align="center">

![Graph Visualization](doc/graph.png)

_This diagram is automatically updated from the codebase. This is our current agentic system architecture._

</div>

## ❀️ Contributing

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.
Expand Down
Binary file added doc/graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions minitap/mobile_use/graph/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from langgraph.constants import END, START
from langgraph.graph import StateGraph
from langgraph.graph.state import CompiledStateGraph

from minitap.mobile_use.agents.contextor.contextor import ContextorNode
from minitap.mobile_use.agents.cortex.cortex import CortexNode
from minitap.mobile_use.agents.executor.executor import ExecutorNode
Expand Down
77 changes: 77 additions & 0 deletions scripts/doc/generate_graph_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""
Script to generate graph visualization from the LangGraph structure.
This creates both a PNG image and a Mermaid markdown file.
It updates the README.md file with the generated graph.
"""

import asyncio
import sys
from pathlib import Path

from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles
from langchain_core.runnables.graph_mermaid import draw_mermaid_png
from langgraph.graph.state import CompiledStateGraph

from minitap.mobile_use.clients.device_hardware_client import DeviceHardwareClient
from minitap.mobile_use.clients.screen_api_client import ScreenApiClient
from minitap.mobile_use.config import get_default_llm_config
from minitap.mobile_use.context import (
DeviceContext,
DevicePlatform,
)

sys.path.append(str(Path(__file__).parent.parent))


async def generate_graph_docs():
"""Generate graph visualization as PNG."""
from minitap.mobile_use.context import MobileUseContext
from minitap.mobile_use.graph.graph import get_graph

print("Loading graph structure...")
ctx = MobileUseContext(
device=DeviceContext(
host_platform="LINUX",
mobile_platform=DevicePlatform.ANDROID,
device_id="device_id",
device_width=1080,
device_height=1920,
),
hw_bridge_client=DeviceHardwareClient(base_url="http://localhost:8000"),
screen_api_client=ScreenApiClient(base_url="http://localhost:8000"),
llm_config=get_default_llm_config(),
)

print("Generating graph...")
graph: CompiledStateGraph = await get_graph(ctx)

png_path = Path(__file__).parent.parent.parent / "doc" / "graph.png"
print(f"Generating PNG at {png_path}...")

mermaid_text = graph.get_graph().draw_mermaid(
node_colors=NodeStyles(
default="fill:#d0c4f2,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
first="fill:#9998e1,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
last="fill:#9998e1,stroke:#b3b3b3,stroke-width:1px,color:#ffffff",
),
curve_style=CurveStyle.LINEAR,
frontmatter_config={
"config": {
"themeVariables": {
"lineColor": "#ffffff",
},
}
},
)

draw_mermaid_png(
mermaid_syntax=mermaid_text,
output_file_path=str(png_path),
draw_method=MermaidDrawMethod.API,
background_color=None,
)


if __name__ == "__main__":
asyncio.run(generate_graph_docs())