droidrun 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. droidrun-0.3.3/.github/workflows/bounty.yml +134 -0
  2. {droidrun-0.3.2 → droidrun-0.3.3}/.github/workflows/publish.yml +2 -1
  3. {droidrun-0.3.2 → droidrun-0.3.3}/.gitignore +3 -0
  4. {droidrun-0.3.2 → droidrun-0.3.3}/PKG-INFO +21 -8
  5. {droidrun-0.3.2 → droidrun-0.3.3}/README.md +16 -6
  6. droidrun-0.3.3/docs/docs.json +147 -0
  7. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/concepts/android-tools.mdx +6 -6
  8. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/concepts/models.mdx +4 -2
  9. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/__init__.py +6 -2
  10. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/codeact/codeact_agent.py +7 -6
  11. droidrun-0.3.3/droidrun/agent/common/events.py +47 -0
  12. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/personas/__init__.py +2 -0
  13. droidrun-0.3.3/droidrun/agent/context/personas/big_agent.py +96 -0
  14. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/personas/ui_expert.py +1 -0
  15. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/droid/droid_agent.py +15 -6
  16. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/planner/planner_agent.py +2 -2
  17. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/utils/executer.py +10 -2
  18. droidrun-0.3.3/droidrun/agent/utils/trajectory.py +431 -0
  19. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/cli/main.py +73 -36
  20. droidrun-0.3.3/droidrun/macro/__init__.py +14 -0
  21. droidrun-0.3.3/droidrun/macro/__main__.py +10 -0
  22. droidrun-0.3.3/droidrun/macro/cli.py +228 -0
  23. droidrun-0.3.3/droidrun/macro/replay.py +309 -0
  24. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/portal.py +16 -17
  25. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/telemetry/tracker.py +3 -2
  26. droidrun-0.3.3/droidrun/tools/adb.py +1139 -0
  27. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/tools/ios.py +163 -163
  28. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/tools/tools.py +32 -14
  29. {droidrun-0.3.2 → droidrun-0.3.3}/pyproject.toml +7 -4
  30. droidrun-0.3.2/docs/docs.json +0 -133
  31. droidrun-0.3.2/droidrun/adb/__init__.py +0 -13
  32. droidrun-0.3.2/droidrun/adb/device.py +0 -345
  33. droidrun-0.3.2/droidrun/adb/manager.py +0 -93
  34. droidrun-0.3.2/droidrun/adb/wrapper.py +0 -226
  35. droidrun-0.3.2/droidrun/agent/common/events.py +0 -4
  36. droidrun-0.3.2/droidrun/agent/utils/trajectory.py +0 -184
  37. droidrun-0.3.2/droidrun/tools/adb.py +0 -671
  38. {droidrun-0.3.2 → droidrun-0.3.3}/CHANGELOG.md +0 -0
  39. {droidrun-0.3.2 → droidrun-0.3.3}/CONTRIBUTING.md +0 -0
  40. {droidrun-0.3.2 → droidrun-0.3.3}/LICENSE +0 -0
  41. {droidrun-0.3.2 → droidrun-0.3.3}/MANIFEST.in +0 -0
  42. {droidrun-0.3.2 → droidrun-0.3.3}/docs/.generated-files.txt +0 -0
  43. {droidrun-0.3.2 → droidrun-0.3.3}/docs/favicon.png +0 -0
  44. {droidrun-0.3.2 → droidrun-0.3.3}/docs/logo/dark.svg +0 -0
  45. {droidrun-0.3.2 → droidrun-0.3.3}/docs/logo/light.svg +0 -0
  46. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v1/concepts/agent.mdx +0 -0
  47. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v1/concepts/android-control.mdx +0 -0
  48. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v1/concepts/portal-app.mdx +0 -0
  49. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v1/overview.mdx +0 -0
  50. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v1/quickstart.mdx +0 -0
  51. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/concepts/agent.mdx +0 -0
  52. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/concepts/android-control.mdx +0 -0
  53. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/concepts/planning.mdx +0 -0
  54. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/concepts/portal-app.mdx +0 -0
  55. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/concepts/tracing.mdx +0 -0
  56. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/overview.mdx +0 -0
  57. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v2/quickstart.mdx +0 -0
  58. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/concepts/agent.mdx +0 -0
  59. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/concepts/portal-app.mdx +0 -0
  60. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/cli.mdx +0 -0
  61. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/gemini.mdx +0 -0
  62. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/ollama.mdx +0 -0
  63. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/openailike.mdx +0 -0
  64. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/overview.mdx +0 -0
  65. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/guides/telemetry.mdx +0 -0
  66. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/images/portal_apk.png +0 -0
  67. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/overview.mdx +0 -0
  68. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/quickstart.mdx +0 -0
  69. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/sdk/adb-tools.mdx +0 -0
  70. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/sdk/adb-utils.mdx +0 -0
  71. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/sdk/base-tools.mdx +0 -0
  72. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/sdk/droid-agent.mdx +0 -0
  73. {droidrun-0.3.2 → droidrun-0.3.3}/docs/v3/sdk/ios-tools.mdx +0 -0
  74. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/__main__.py +0 -0
  75. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/__init__.py +0 -0
  76. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/codeact/__init__.py +0 -0
  77. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/codeact/events.py +0 -0
  78. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/codeact/prompts.py +0 -0
  79. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/common/default.py +0 -0
  80. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/__init__.py +0 -0
  81. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/agent_persona.py +0 -0
  82. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/context_injection_manager.py +0 -0
  83. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/episodic_memory.py +0 -0
  84. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/personas/app_starter.py +0 -0
  85. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/personas/default.py +0 -0
  86. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/reflection.py +0 -0
  87. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/context/task_manager.py +0 -0
  88. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/droid/__init__.py +0 -0
  89. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/droid/events.py +0 -0
  90. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/oneflows/reflector.py +0 -0
  91. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/planner/__init__.py +0 -0
  92. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/planner/events.py +0 -0
  93. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/planner/prompts.py +0 -0
  94. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/utils/__init__.py +0 -0
  95. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/utils/async_utils.py +0 -0
  96. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/utils/chat_utils.py +0 -0
  97. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/agent/utils/llm_picker.py +0 -0
  98. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/cli/__init__.py +0 -0
  99. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/cli/logs.py +0 -0
  100. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/telemetry/__init__.py +0 -0
  101. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/telemetry/events.py +0 -0
  102. {droidrun-0.3.2 → droidrun-0.3.3}/droidrun/tools/__init__.py +0 -0
  103. {droidrun-0.3.2 → droidrun-0.3.3}/gen-docs-sdk-ref.sh +0 -0
  104. {droidrun-0.3.2 → droidrun-0.3.3}/setup.py +0 -0
  105. {droidrun-0.3.2 → droidrun-0.3.3}/static/droidrun-dark.png +0 -0
  106. {droidrun-0.3.2 → droidrun-0.3.3}/static/droidrun.png +0 -0
@@ -0,0 +1,134 @@
1
+ name: "Project V2: Status ← issue label"
2
+
3
+ on:
4
+ issues:
5
+ types: [labeled]
6
+
7
+ env:
8
+ ORG: droidrun
9
+ PROJECT_NUMBER: 2
10
+ PROJECT_TOKEN: ${{ secrets.BOUNTY_SECRET }}
11
+
12
+ jobs:
13
+ update_status:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+
17
+ - name: Fetch project & field metadata
18
+ id: metadata
19
+ env:
20
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
21
+ run: |
22
+ # 1) Query projectV2 ID and the Status field + its options
23
+ gh api graphql -f query='
24
+ query($org:String!,$num:Int!){
25
+ organization(login:$org){
26
+ projectV2(number:$num){
27
+ id
28
+ fields(first:20){
29
+ nodes{
30
+ ... on ProjectV2SingleSelectField{
31
+ id
32
+ name
33
+ options { id name }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }' \
40
+ -f org="${ORG}" -F num=${PROJECT_NUMBER} \
41
+ --jq '
42
+ .data.organization.projectV2 as $p |
43
+ ($p.id) as $projId |
44
+ ($p.fields.nodes[] | select(.name=="Status")) as $f |
45
+ {
46
+ projectId: $projId,
47
+ statusFieldId: $f.id,
48
+ options: ($f.options | map({(.name): .id}) | add)
49
+ }
50
+ ' > meta.json
51
+
52
+ # expose to GH env
53
+ echo "PROJECT_ID=$(jq -r .projectId meta.json)" >> $GITHUB_ENV
54
+ echo "STATUS_FIELD_ID=$(jq -r .statusFieldId meta.json)" >> $GITHUB_ENV
55
+ # options is an object like {"Eligible":"ID1","Bounty Posted":"ID2",...}
56
+ echo "STATUS_OPTIONS=$(jq -c .options meta.json)" >> $GITHUB_ENV
57
+
58
+ - name: Determine target option ID
59
+ id: pick
60
+ run: |
61
+ LABEL="${{ github.event.label.name }}"
62
+ # map label→ field option name
63
+ case "$LABEL" in
64
+ eligible) OPT_NAME="📝 Eligible" ;;
65
+ bounty-official) OPT_NAME="💰 Bounty" ;;
66
+ claimed) OPT_NAME="🛠️ In Progress" ;;
67
+ *) echo "No matching status for $LABEL"; exit 0 ;;
68
+ esac
69
+
70
+ # extract from JSON map
71
+ OPT_ID=$(echo "$STATUS_OPTIONS" | jq -r --arg name "$OPT_NAME" '.[$name]')
72
+ echo "OPTION_ID=$OPT_ID" >> $GITHUB_ENV
73
+
74
+ - name: Ensure issue is in the project
75
+ id: add_if_missing
76
+ env:
77
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
78
+ run: |
79
+ ISSUE_NODE_ID=$(gh api graphql -f query='
80
+ query($owner:String!,$repo:String!,$number:Int!){
81
+ repository(owner:$owner, name:$repo){
82
+ issue(number:$number){
83
+ id
84
+ projectItems(first:1){
85
+ nodes{ id }
86
+ }
87
+ }
88
+ }
89
+ }' \
90
+ -f owner="droidrun" \
91
+ -f repo="droidrun" \
92
+ -F number=104 \
93
+ --jq '.data.repository.issue as $i |
94
+ { issueId: $i.id,
95
+ itemId: ($i.projectItems.nodes[0]?.id // "") }' )
96
+
97
+ # Save to file
98
+ echo "$ISSUE_NODE_ID" > issue.json
99
+ ISSUE_ID=$(jq -r .issueId issue.json)
100
+ ITEM_ID=$(jq -r .itemId issue.json)
101
+
102
+ if [ -z "$ITEM_ID" ]; then
103
+ ITEM_ID=$(gh api graphql -f query='
104
+ mutation($proj:ID!,$content:ID!){
105
+ addProjectV2ItemById(input:{projectId:$proj, contentId:$content}){
106
+ item { id }
107
+ }
108
+ }' \
109
+ -f proj="${PROJECT_ID}" -f content="$ISSUE_ID" \
110
+ --jq '.data.addProjectV2ItemById.item.id')
111
+ fi
112
+ echo "ITEM_ID=$ITEM_ID" >> $GITHUB_ENV
113
+
114
+ - name: Update Status field
115
+ env:
116
+ GH_TOKEN: ${{ env.PROJECT_TOKEN }}
117
+ run: |
118
+ gh api graphql -f query='
119
+ mutation($proj:ID!,$item:ID!,$field:ID!,$opt:String!){
120
+ updateProjectV2ItemFieldValue(input:{
121
+ projectId: $proj,
122
+ itemId: $item,
123
+ fieldId: $field,
124
+ value: {
125
+ singleSelectOptionId: $opt
126
+ }
127
+ }) {
128
+ projectV2Item { id }
129
+ }
130
+ }' \
131
+ -f proj="${PROJECT_ID}" \
132
+ -f item="${ITEM_ID}" \
133
+ -f field="${STATUS_FIELD_ID}" \
134
+ -f opt="${OPTION_ID}"
@@ -53,6 +53,7 @@ jobs:
53
53
 
54
54
  publish-to-testpypi:
55
55
  name: Publish Python 🐍 distribution 📦 to TestPyPI
56
+ if: startsWith(github.ref, 'refs/tags/')
56
57
  needs:
57
58
  - build
58
59
  runs-on: ubuntu-latest
@@ -73,4 +74,4 @@ jobs:
73
74
  - name: Publish distribution 📦 to TestPyPI
74
75
  uses: pypa/gh-action-pypi-publish@release/v1
75
76
  with:
76
- repository-url: https://test.pypi.org/legacy/
77
+ repository-url: https://test.pypi.org/legacy/
@@ -22,3 +22,6 @@ messages_log.json
22
22
  patch_apis.py
23
23
  .git
24
24
  .arize-phoenix
25
+
26
+
27
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: droidrun
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: A framework for controlling Android devices through LLM agents
5
5
  Project-URL: Homepage, https://github.com/droidrun/droidrun
6
6
  Project-URL: Bug Tracker, https://github.com/droidrun/droidrun/issues
@@ -25,9 +25,11 @@ Classifier: Topic :: Software Development :: Testing
25
25
  Classifier: Topic :: Software Development :: Testing :: Acceptance
26
26
  Classifier: Topic :: System :: Emulators
27
27
  Classifier: Topic :: Utilities
28
- Requires-Python: >=3.10
28
+ Requires-Python: >=3.11
29
+ Requires-Dist: adbutils==2.10.0
29
30
  Requires-Dist: aiofiles>=23.0.0
30
31
  Requires-Dist: anthropic>=0.7.0
32
+ Requires-Dist: apkutils==2.0.0
31
33
  Requires-Dist: arize-phoenix
32
34
  Requires-Dist: click>=8.1.0
33
35
  Requires-Dist: llama-index
@@ -44,6 +46,7 @@ Requires-Dist: posthog==6.0.2
44
46
  Requires-Dist: pydantic>=2.0.0
45
47
  Requires-Dist: python-dotenv>=1.0.0
46
48
  Requires-Dist: rich>=13.0.0
49
+ Requires-Dist: typing-extensions
47
50
  Provides-Extra: dev
48
51
  Requires-Dist: bandit>=1.7.0; extra == 'dev'
49
52
  Requires-Dist: black>=23.0.0; extra == 'dev'
@@ -64,6 +67,12 @@ Description-Content-Type: text/markdown
64
67
  [![Benchmark](https://img.shields.io/badge/Benchmark-🏅-teal)](https://droidrun.ai/benchmark)
65
68
  [![Twitter Follow](https://img.shields.io/twitter/follow/droid_run?style=social)](https://x.com/droid_run)
66
69
 
70
+ <picture>
71
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=dark&period=daily&t=1753948032207">
72
+ <source media="(prefers-color-scheme: light)" srcset="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=neutral&period=daily&t=1753948125523">
73
+ <a href="https://www.producthunt.com/products/droidrun-framework-for-mobile-agent?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-droidrun" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=neutral&period=daily&t=1753948125523" alt="Droidrun - Give&#0032;AI&#0032;native&#0032;control&#0032;of&#0032;physical&#0032;&#0038;&#0032;virtual&#0032;phones&#0046; | Product Hunt" style="width: 200px; height: 54px;" width="200" height="54" /></a>
74
+ </picture>
75
+
67
76
 
68
77
 
69
78
  DroidRun is a powerful framework for controlling Android and iOS devices through LLM agents. It allows you to automate device interactions using natural language commands. [Checkout our benchmark results](https://droidrun.ai/benchmark)
@@ -91,17 +100,21 @@ Read on how to get droidrun up and running within seconds in [our docs](https://
91
100
 
92
101
  ## 🎬 Demo Videos
93
102
 
94
- 1. **Group Chat Summarization**: Let DroidRun summarize an escalated group chat for you.
103
+ 1. **Accommodation booking**: Let Droidrun search for an apartment for you
104
+
105
+ [![Droidrun Accommodation Booking Demo](https://img.youtube.com/vi/VUpCyq1PSXw/0.jpg)](https://youtu.be/VUpCyq1PSXw)
106
+
107
+ <br>
95
108
 
96
- [![Group Chat Summarizer](https://img.youtube.com/vi/ofEnSUHHxX8/0.jpg)](https://www.youtube.com/watch?v=ofEnSUHHxX8)
109
+ 2. **Trend Hunter**: Let Droidrun hunt down trending posts
97
110
 
98
- 2. **Travel Search Assistant**: Wittness DroidRun looking for the cheapest stay and share it with a colleague on telegram.
111
+ [![Droidrun Trend Hunter Demo](https://img.youtube.com/vi/7V8S2f8PnkQ/0.jpg)](https://youtu.be/7V8S2f8PnkQ)
99
112
 
100
- [![Travel Search Assistant](https://img.youtube.com/vi/QgtRaLS3NBM/0.jpg)](https://www.youtube.com/watch?v=QgtRaLS3NBM)
113
+ <br>
101
114
 
102
- 3. **Automate TikTok Shopping**: See how DroidRun looks for a stanley cup on TikTok Shop and send the product details via email.
115
+ 3. **Streak Saver**: Let Droidrun save your streak on your favorite language learning app
103
116
 
104
- [![TikTok Shopping Assistant](https://img.youtube.com/vi/ol3bivBAmn4/0.jpg)](https://www.youtube.com/watch?v=ol3bivBAmn4)
117
+ [![Droidrun Streak Saver Demo](https://img.youtube.com/vi/B5q2B467HKw/0.jpg)](https://youtu.be/B5q2B467HKw)
105
118
 
106
119
 
107
120
  ## 💡 Example Use Cases
@@ -10,6 +10,12 @@
10
10
  [![Benchmark](https://img.shields.io/badge/Benchmark-🏅-teal)](https://droidrun.ai/benchmark)
11
11
  [![Twitter Follow](https://img.shields.io/twitter/follow/droid_run?style=social)](https://x.com/droid_run)
12
12
 
13
+ <picture>
14
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=dark&period=daily&t=1753948032207">
15
+ <source media="(prefers-color-scheme: light)" srcset="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=neutral&period=daily&t=1753948125523">
16
+ <a href="https://www.producthunt.com/products/droidrun-framework-for-mobile-agent?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-droidrun" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=983810&theme=neutral&period=daily&t=1753948125523" alt="Droidrun - Give&#0032;AI&#0032;native&#0032;control&#0032;of&#0032;physical&#0032;&#0038;&#0032;virtual&#0032;phones&#0046; | Product Hunt" style="width: 200px; height: 54px;" width="200" height="54" /></a>
17
+ </picture>
18
+
13
19
 
14
20
 
15
21
  DroidRun is a powerful framework for controlling Android and iOS devices through LLM agents. It allows you to automate device interactions using natural language commands. [Checkout our benchmark results](https://droidrun.ai/benchmark)
@@ -37,17 +43,21 @@ Read on how to get droidrun up and running within seconds in [our docs](https://
37
43
 
38
44
  ## 🎬 Demo Videos
39
45
 
40
- 1. **Group Chat Summarization**: Let DroidRun summarize an escalated group chat for you.
46
+ 1. **Accommodation booking**: Let Droidrun search for an apartment for you
47
+
48
+ [![Droidrun Accommodation Booking Demo](https://img.youtube.com/vi/VUpCyq1PSXw/0.jpg)](https://youtu.be/VUpCyq1PSXw)
49
+
50
+ <br>
41
51
 
42
- [![Group Chat Summarizer](https://img.youtube.com/vi/ofEnSUHHxX8/0.jpg)](https://www.youtube.com/watch?v=ofEnSUHHxX8)
52
+ 2. **Trend Hunter**: Let Droidrun hunt down trending posts
43
53
 
44
- 2. **Travel Search Assistant**: Wittness DroidRun looking for the cheapest stay and share it with a colleague on telegram.
54
+ [![Droidrun Trend Hunter Demo](https://img.youtube.com/vi/7V8S2f8PnkQ/0.jpg)](https://youtu.be/7V8S2f8PnkQ)
45
55
 
46
- [![Travel Search Assistant](https://img.youtube.com/vi/QgtRaLS3NBM/0.jpg)](https://www.youtube.com/watch?v=QgtRaLS3NBM)
56
+ <br>
47
57
 
48
- 3. **Automate TikTok Shopping**: See how DroidRun looks for a stanley cup on TikTok Shop and send the product details via email.
58
+ 3. **Streak Saver**: Let Droidrun save your streak on your favorite language learning app
49
59
 
50
- [![TikTok Shopping Assistant](https://img.youtube.com/vi/ol3bivBAmn4/0.jpg)](https://www.youtube.com/watch?v=ol3bivBAmn4)
60
+ [![Droidrun Streak Saver Demo](https://img.youtube.com/vi/B5q2B467HKw/0.jpg)](https://youtu.be/B5q2B467HKw)
51
61
 
52
62
 
53
63
  ## 💡 Example Use Cases
@@ -0,0 +1,147 @@
1
+ {
2
+ "$schema": "https://mintlify.com/docs.json",
3
+ "theme": "mint",
4
+ "name": "DroidRun",
5
+ "colors": {
6
+ "primary": "#0D9373",
7
+ "light": "#07C983",
8
+ "dark": "#0D9373"
9
+ },
10
+ "favicon": "/favicon.png",
11
+ "navigation": {
12
+ "tabs": [
13
+ {
14
+ "tab": "Framework",
15
+ "versions": [
16
+ {
17
+ "version": "0.3.2",
18
+ "groups": [
19
+ {
20
+ "group": "Introduction",
21
+ "pages": [
22
+ "v3/overview",
23
+ "v3/quickstart"
24
+ ]
25
+ },
26
+ {
27
+ "group": "Guides",
28
+ "pages": [
29
+ "v3/guides/overview",
30
+ "v3/guides/cli",
31
+ "v3/guides/gemini",
32
+ "v3/guides/openailike",
33
+ "v3/guides/ollama",
34
+ "v3/guides/telemetry"
35
+ ]
36
+ },
37
+ {
38
+ "group": "Core Concepts",
39
+ "pages": [
40
+ "v3/concepts/agent",
41
+ "v3/concepts/models",
42
+ "v3/concepts/android-tools",
43
+ "v3/concepts/portal-app"
44
+ ]
45
+ },
46
+ {
47
+ "group": "SDK Reference",
48
+ "pages": [
49
+ "v3/sdk/droid-agent",
50
+ "v3/sdk/adb-tools",
51
+ "v3/sdk/ios-tools",
52
+ "v3/sdk/base-tools",
53
+ "v3/sdk/adb-utils"
54
+ ]
55
+ }
56
+ ]
57
+ },
58
+ {
59
+ "version": "0.2.0",
60
+ "groups": [
61
+ {
62
+ "group": "Getting Started",
63
+ "pages": [
64
+ "v2/overview",
65
+ "v2/quickstart"
66
+ ]
67
+ },
68
+ {
69
+ "group": "Core Concepts",
70
+ "pages": [
71
+ "v2/concepts/agent",
72
+ "v2/concepts/planning",
73
+ "v2/concepts/android-control",
74
+ "v2/concepts/portal-app",
75
+ "v2/concepts/tracing"
76
+ ]
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ "version": "0.1.0",
82
+ "groups": [
83
+ {
84
+ "group": "Getting Started",
85
+ "pages": [
86
+ "v1/overview",
87
+ "v1/quickstart"
88
+ ]
89
+ },
90
+ {
91
+ "group": "Core Concepts",
92
+ "pages": [
93
+ "v1/concepts/agent",
94
+ "v1/concepts/android-control",
95
+ "v1/concepts/portal-app"
96
+ ]
97
+ }
98
+ ]
99
+ }
100
+ ]
101
+ },
102
+ {
103
+ "tab": "Cloud API",
104
+ "versions": [
105
+ {
106
+ "version": "0.1.0",
107
+ "openapi": "https://api.droidrun.ai/v1/openapi.json"
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ },
113
+ "logo": {
114
+ "light": "/logo/light.svg",
115
+ "dark": "/logo/dark.svg"
116
+ },
117
+ "navbar": {
118
+ "links": [
119
+ {
120
+ "label": "GitHub",
121
+ "href": "https://github.com/droidrun/droidrun"
122
+ },
123
+ {
124
+ "label": "Benchmark",
125
+ "href": "https://droidrun.ai/benchmark"
126
+ }
127
+ ],
128
+ "primary": {
129
+ "type": "button",
130
+ "label": "Join Discord",
131
+ "href": "https://discord.gg/gdekvkJFvn"
132
+ }
133
+ },
134
+ "footer": {
135
+ "socials": {
136
+ "github": "https://github.com/droidrun/droidrun",
137
+ "x": "https://x.com/droid_run",
138
+ "discord": "https://discord.gg/gdekvkJFvn",
139
+ "website": "https://droidrun.ai"
140
+ }
141
+ },
142
+ "errors": {
143
+ "404": {
144
+ "redirect": false
145
+ }
146
+ }
147
+ }
@@ -37,12 +37,12 @@ Convenience method to press the Android back button.
37
37
 
38
38
  ```python
39
39
  # UI interaction examples
40
- await tools.get_state() # Cache elements first
41
- await tools.tap_by_index(2) # Tap element
42
- await tools.swipe(500, 200, 500, 800, 400) # Swipe down
43
- await tools.input_text("Hello, World!")
44
- await tools.press_key(66) # Enter key
45
- await tools.back()
40
+ tools.get_state() # Cache elements first
41
+ tools.tap_by_index(2) # Tap element
42
+ tools.swipe(500, 200, 500, 800, 400) # Swipe down
43
+ tools.input_text("Hello, World!")
44
+ tools.press_key(66) # Enter key
45
+ tools.back()
46
46
  ```
47
47
 
48
48
  ## App Management Tools
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 'Supported Models'
3
- description: 'DroidRun is **LLM agnostic**, which means you can use every LLM provider there is.
3
+ description: 'DroidRun is **LLM agnostic**, which means you can use every LLM provider there is.
4
4
 
5
5
  Under the hood, DroidRun leverages [LlamaIndex LLM providers](https://docs.llamaindex.ai/en/stable/api_reference/llms/) to provide seamless integration with all major language model providers. This means you can easily switch between different providers or use multiple providers simultaneously depending on your needs.
6
6
  '
@@ -8,7 +8,7 @@ Under the hood, DroidRun leverages [LlamaIndex LLM providers](https://docs.llama
8
8
 
9
9
  ## Install LLM Provider
10
10
  ```bash
11
- # Install the package for your preffered LLM Provider
11
+ # Install the package for your preferred LLM Provider
12
12
  pip install llama-index-llms-[PROVIDER]
13
13
  ```
14
14
 
@@ -19,6 +19,8 @@ DroidRun supports all major LLM providers through LlamaIndex, including but not
19
19
  - **OpenAI** (GPT-4o, GPT-o3, etc.)
20
20
  - **Anthropic** (Claude models)
21
21
  - **GoogleGenAI** (Gemini)
22
+ - **OpenAILike** (OpenAI-compatible APIs such as OpenRouter, Azure OpenAI, local LM Studio)
23
+ - **DeepSeek** (DeepSeek LLM integrations)
22
24
  - **Azure OpenAI Service**
23
25
  - **AWS Bedrock**
24
26
  - **Cohere**
@@ -6,17 +6,21 @@ __version__ = "0.3.0"
6
6
 
7
7
  # Import main classes for easier access
8
8
  from droidrun.agent.utils.llm_picker import load_llm
9
- from droidrun.adb.manager import DeviceManager
10
9
  from droidrun.tools import Tools, AdbTools, IOSTools
11
10
  from droidrun.agent.droid import DroidAgent
12
11
 
12
+ # Import macro functionality
13
+ from droidrun.macro import MacroPlayer, replay_macro_file, replay_macro_folder
14
+
13
15
 
14
16
  # Make main components available at package level
15
17
  __all__ = [
16
18
  "DroidAgent",
17
- "DeviceManager",
18
19
  "load_llm",
19
20
  "Tools",
20
21
  "AdbTools",
21
22
  "IOSTools",
23
+ "MacroPlayer",
24
+ "replay_macro_file",
25
+ "replay_macro_folder",
22
26
  ]
@@ -97,6 +97,7 @@ class CodeActAgent(Workflow):
97
97
  loop=asyncio.get_event_loop(),
98
98
  locals={},
99
99
  tools=self.tool_list,
100
+ tools_instance=tools_instance,
100
101
  globals={"__builtins__": __builtins__},
101
102
  )
102
103
 
@@ -169,7 +170,7 @@ class CodeActAgent(Workflow):
169
170
  "[yellow]DeepSeek doesnt support images. Disabling screenshots[/]"
170
171
  )
171
172
  elif self.vision == True and context == "screenshot":
172
- screenshot = (await self.tools.take_screenshot())[1]
173
+ screenshot = (self.tools.take_screenshot())[1]
173
174
  ctx.write_event_to_stream(ScreenshotEvent(screenshot=screenshot))
174
175
 
175
176
  await ctx.set("screenshot", screenshot)
@@ -177,7 +178,7 @@ class CodeActAgent(Workflow):
177
178
 
178
179
  if context == "ui_state":
179
180
  try:
180
- state = await self.tools.get_state()
181
+ state = self.tools.get_state()
181
182
  await ctx.set("ui_state", state["a11y_tree"])
182
183
  chat_history = await chat_utils.add_ui_text_block(
183
184
  state["a11y_tree"], chat_history
@@ -189,7 +190,7 @@ class CodeActAgent(Workflow):
189
190
 
190
191
  if context == "packages":
191
192
  chat_history = await chat_utils.add_packages_block(
192
- await self.tools.list_packages(include_system_apps=True),
193
+ self.tools.list_packages(include_system_apps=True),
193
194
  chat_history,
194
195
  )
195
196
 
@@ -242,7 +243,7 @@ class CodeActAgent(Workflow):
242
243
  code = ev.code
243
244
  assert code, "Code cannot be empty."
244
245
  logger.info(f"⚡ Executing action...")
245
- logger.debug(f"Code to execute:\n```python\n{code}\n```")
246
+ logger.info(f"Code to execute:\n```python\n{code}\n```")
246
247
 
247
248
  try:
248
249
  self.code_exec_counter += 1
@@ -398,13 +399,13 @@ class CodeActAgent(Workflow):
398
399
  ui_state = None
399
400
 
400
401
  try:
401
- _, screenshot_bytes = await self.tools.take_screenshot()
402
+ _, screenshot_bytes = self.tools.take_screenshot()
402
403
  screenshot = screenshot_bytes
403
404
  except Exception as e:
404
405
  logger.warning(f"Failed to capture final screenshot: {e}")
405
406
 
406
407
  try:
407
- (a11y_tree, phone_state) = await self.tools.get_state()
408
+ (a11y_tree, phone_state) = self.tools.get_state()
408
409
  except Exception as e:
409
410
  logger.warning(f"Failed to capture final UI state: {e}")
410
411
 
@@ -0,0 +1,47 @@
1
+ from llama_index.core.workflow import Event
2
+
3
+ class ScreenshotEvent(Event):
4
+ screenshot: bytes
5
+
6
+ class MacroEvent(Event):
7
+ """Base class for coordinate-based action events"""
8
+ action_type: str
9
+ description: str
10
+
11
+ class TapActionEvent(MacroEvent):
12
+ """Event for tap actions with coordinates"""
13
+ x: int
14
+ y: int
15
+ element_index: int = None
16
+ element_text: str = ""
17
+ element_bounds: str = ""
18
+
19
+ class SwipeActionEvent(MacroEvent):
20
+ """Event for swipe actions with coordinates"""
21
+ start_x: int
22
+ start_y: int
23
+ end_x: int
24
+ end_y: int
25
+ duration_ms: int
26
+
27
+ class DragActionEvent(MacroEvent):
28
+ """Event for drag actions with coordinates"""
29
+ start_x: int
30
+ start_y: int
31
+ end_x: int
32
+ end_y: int
33
+ duration_ms: int
34
+
35
+ class InputTextActionEvent(MacroEvent):
36
+ """Event for text input actions"""
37
+ text: str
38
+
39
+ class KeyPressActionEvent(MacroEvent):
40
+ """Event for key press actions"""
41
+ keycode: int
42
+ key_name: str = ""
43
+
44
+ class StartAppEvent(MacroEvent):
45
+ """"Event for starting an app"""
46
+ package: str
47
+ activity: str = None
@@ -1,9 +1,11 @@
1
1
  from .default import DEFAULT
2
2
  from .ui_expert import UI_EXPERT
3
3
  from .app_starter import APP_STARTER_EXPERT
4
+ from .big_agent import BIG_AGENT
4
5
 
5
6
  __all__ = [
6
7
  'DEFAULT',
7
8
  'UI_EXPERT',
8
9
  'APP_STARTER_EXPERT',
10
+ 'BIG_AGENT',
9
11
  ]