droidrun 0.3.9__tar.gz → 0.3.10.dev2__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.
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/.github/workflows/publish.yml +18 -22
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/PKG-INFO +6 -3
- droidrun-0.3.10.dev2/config.yaml +91 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/__init__.py +2 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/__main__.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/__init__.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/codeact/__init__.py +1 -4
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/codeact/codeact_agent.py +66 -40
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/codeact/events.py +6 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/codeact/prompts.py +2 -2
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/common/events.py +4 -2
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/__init__.py +1 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/agent_persona.py +2 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/context_injection_manager.py +6 -6
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/episodic_memory.py +5 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/personas/__init__.py +3 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/personas/app_starter.py +3 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/personas/big_agent.py +3 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/personas/default.py +3 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/personas/ui_expert.py +5 -5
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/context/task_manager.py +15 -17
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/droid/__init__.py +1 -1
- droidrun-0.3.10.dev2/droidrun/agent/droid/droid_agent.py +637 -0
- droidrun-0.3.10.dev2/droidrun/agent/droid/events.py +115 -0
- droidrun-0.3.10.dev2/droidrun/agent/executor/__init__.py +13 -0
- droidrun-0.3.10.dev2/droidrun/agent/executor/events.py +24 -0
- droidrun-0.3.10.dev2/droidrun/agent/executor/executor_agent.py +327 -0
- droidrun-0.3.10.dev2/droidrun/agent/executor/prompts.py +136 -0
- droidrun-0.3.10.dev2/droidrun/agent/manager/__init__.py +18 -0
- droidrun-0.3.10.dev2/droidrun/agent/manager/events.py +20 -0
- droidrun-0.3.10.dev2/droidrun/agent/manager/manager_agent.py +459 -0
- droidrun-0.3.10.dev2/droidrun/agent/manager/prompts.py +223 -0
- droidrun-0.3.10.dev2/droidrun/agent/oneflows/app_starter_workflow.py +118 -0
- droidrun-0.3.10.dev2/droidrun/agent/oneflows/text_manipulator.py +204 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/planner/__init__.py +3 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/planner/events.py +6 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/planner/planner_agent.py +27 -42
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/planner/prompts.py +2 -2
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/usage.py +11 -11
- droidrun-0.3.10.dev2/droidrun/agent/utils/__init__.py +13 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/utils/async_utils.py +2 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/utils/chat_utils.py +48 -60
- droidrun-0.3.10.dev2/droidrun/agent/utils/device_state_formatter.py +177 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/utils/executer.py +12 -11
- droidrun-0.3.10.dev2/droidrun/agent/utils/inference.py +114 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/utils/llm_picker.py +2 -0
- droidrun-0.3.10.dev2/droidrun/agent/utils/message_utils.py +85 -0
- droidrun-0.3.10.dev2/droidrun/agent/utils/tools.py +220 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/utils/trajectory.py +8 -7
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/cli/__init__.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/cli/logs.py +29 -28
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/cli/main.py +279 -143
- droidrun-0.3.10.dev2/droidrun/config_manager/__init__.py +25 -0
- droidrun-0.3.10.dev2/droidrun/config_manager/config_manager.py +583 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/macro/__init__.py +2 -2
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/macro/__main__.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/macro/cli.py +36 -34
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/macro/replay.py +7 -9
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/portal.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/telemetry/__init__.py +2 -2
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/telemetry/events.py +3 -4
- droidrun-0.3.10.dev2/droidrun/telemetry/phoenix.py +173 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/telemetry/tracker.py +7 -5
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/tools/adb.py +210 -82
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/tools/ios.py +7 -5
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/tools/tools.py +25 -8
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/pyproject.toml +10 -4
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/setup.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/uv.lock +26 -710
- droidrun-0.3.9/droidrun/agent/common/default.py +0 -5
- droidrun-0.3.9/droidrun/agent/context/reflection.py +0 -20
- droidrun-0.3.9/droidrun/agent/droid/droid_agent.py +0 -490
- droidrun-0.3.9/droidrun/agent/droid/events.py +0 -33
- droidrun-0.3.9/droidrun/agent/oneflows/reflector.py +0 -265
- droidrun-0.3.9/droidrun/agent/utils/__init__.py +0 -3
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/.github/workflows/bounty.yml +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/.gitignore +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/.python-version +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/CHANGELOG.md +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/CONTRIBUTING.md +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/LICENSE +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/MANIFEST.in +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/README.md +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/.generated-files.txt +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/docs.json +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/favicon.png +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/logo/dark.svg +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/logo/light.svg +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v1/concepts/agent.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v1/concepts/android-control.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v1/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v1/overview.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v1/quickstart.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/concepts/agent.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/concepts/android-control.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/concepts/planning.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/concepts/tracing.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/overview.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v2/quickstart.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/concepts/agent.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/concepts/android-tools.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/concepts/models.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/cli.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/gemini.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/ollama.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/openailike.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/overview.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/guides/telemetry.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/images/portal_apk.png +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/overview.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/quickstart.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/sdk/adb-tools.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/sdk/base-tools.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/sdk/droid-agent.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/docs/v3/sdk/ios-tools.mdx +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/agent/common/constants.py +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/droidrun/tools/__init__.py +1 -1
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/gen-docs-sdk-ref.sh +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/static/droidrun-dark.png +0 -0
- {droidrun-0.3.9 → droidrun-0.3.10.dev2}/static/droidrun.png +0 -0
@@ -1,12 +1,10 @@
|
|
1
1
|
name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
|
2
|
-
|
3
2
|
on: push
|
4
3
|
|
5
4
|
jobs:
|
6
5
|
build:
|
7
6
|
name: Build distribution 📦
|
8
7
|
runs-on: ubuntu-latest
|
9
|
-
|
10
8
|
steps:
|
11
9
|
- uses: actions/checkout@v4
|
12
10
|
with:
|
@@ -29,49 +27,47 @@ jobs:
|
|
29
27
|
name: python-package-distributions
|
30
28
|
path: dist/
|
31
29
|
|
32
|
-
publish-to-
|
33
|
-
name:
|
34
|
-
|
35
|
-
if:
|
30
|
+
publish-to-testpypi:
|
31
|
+
name: Publish Python 🐍 distribution 📦 to TestPyPI
|
32
|
+
# Only runs on dev branch
|
33
|
+
if: github.ref == 'refs/heads/dev'
|
36
34
|
needs:
|
37
35
|
- build
|
38
36
|
runs-on: ubuntu-latest
|
39
37
|
environment:
|
40
|
-
name:
|
41
|
-
url: https://pypi.org/p/droidrun
|
38
|
+
name: testpypi
|
39
|
+
url: https://test.pypi.org/p/droidrun
|
42
40
|
permissions:
|
43
41
|
id-token: write
|
44
|
-
|
45
42
|
steps:
|
46
43
|
- name: Download all the dists
|
47
44
|
uses: actions/download-artifact@v4
|
48
45
|
with:
|
49
46
|
name: python-package-distributions
|
50
47
|
path: dist/
|
51
|
-
- name: Publish distribution 📦 to
|
48
|
+
- name: Publish distribution 📦 to TestPyPI
|
52
49
|
uses: pypa/gh-action-pypi-publish@release/v1
|
50
|
+
with:
|
51
|
+
repository-url: https://test.pypi.org/legacy/
|
53
52
|
|
54
|
-
publish-to-
|
55
|
-
name:
|
56
|
-
|
53
|
+
publish-to-pypi:
|
54
|
+
name: >-
|
55
|
+
Publish Python 🐍 distribution 📦 to PyPI
|
56
|
+
# Only runs on production tags (v*)
|
57
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
57
58
|
needs:
|
58
59
|
- build
|
59
60
|
runs-on: ubuntu-latest
|
60
|
-
|
61
61
|
environment:
|
62
|
-
name:
|
63
|
-
url: https://
|
64
|
-
|
62
|
+
name: pypi
|
63
|
+
url: https://pypi.org/p/droidrun
|
65
64
|
permissions:
|
66
65
|
id-token: write
|
67
|
-
|
68
66
|
steps:
|
69
67
|
- name: Download all the dists
|
70
68
|
uses: actions/download-artifact@v4
|
71
69
|
with:
|
72
70
|
name: python-package-distributions
|
73
71
|
path: dist/
|
74
|
-
- name: Publish distribution 📦 to
|
75
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
76
|
-
with:
|
77
|
-
repository-url: https://test.pypi.org/legacy/
|
72
|
+
- name: Publish distribution 📦 to PyPI
|
73
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: droidrun
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.10.dev2
|
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
|
@@ -27,10 +27,9 @@ Classifier: Topic :: Software Development :: Testing
|
|
27
27
|
Classifier: Topic :: Software Development :: Testing :: Acceptance
|
28
28
|
Classifier: Topic :: System :: Emulators
|
29
29
|
Classifier: Topic :: Utilities
|
30
|
-
Requires-Python: >=3.
|
30
|
+
Requires-Python: >=3.13
|
31
31
|
Requires-Dist: adbutils>=2.10.2
|
32
32
|
Requires-Dist: apkutils==2.0.0
|
33
|
-
Requires-Dist: llama-index-llms-google-genai>=0.6.2
|
34
33
|
Requires-Dist: llama-index==0.14.4
|
35
34
|
Requires-Dist: posthog>=6.7.6
|
36
35
|
Requires-Dist: pydantic>=2.11.10
|
@@ -54,6 +53,10 @@ Provides-Extra: openai
|
|
54
53
|
Requires-Dist: llama-index-llms-openai-like>=0.5.1; extra == 'openai'
|
55
54
|
Requires-Dist: llama-index-llms-openai>=0.5.6; extra == 'openai'
|
56
55
|
Requires-Dist: openai>=1.99.1; extra == 'openai'
|
56
|
+
Provides-Extra: openrouter
|
57
|
+
Requires-Dist: llama-index-llms-openrouter>=0.4.2; extra == 'openrouter'
|
58
|
+
Provides-Extra: phoenix
|
59
|
+
Requires-Dist: arize-phoenix>=12.3.0; extra == 'phoenix'
|
57
60
|
Description-Content-Type: text/markdown
|
58
61
|
|
59
62
|
<picture>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# DroidRun Configuration File
|
2
|
+
# This file is auto-generated. Edit values as needed.
|
3
|
+
|
4
|
+
# === Agent Settings ===
|
5
|
+
agent:
|
6
|
+
# Maximum number of steps per task
|
7
|
+
max_steps: 15
|
8
|
+
# Enable vision capabilities per agent (screenshots)
|
9
|
+
vision:
|
10
|
+
manager: true
|
11
|
+
executor: true
|
12
|
+
codeact: true
|
13
|
+
# Enable planning with reasoning mode
|
14
|
+
reasoning: true
|
15
|
+
# Sleep duration after each action, waits for ui state to be updated (seconds)
|
16
|
+
after_sleep_action: 1.0
|
17
|
+
|
18
|
+
|
19
|
+
wait_for_stable_ui: 0.3 # TODO: doesn't do anything now
|
20
|
+
|
21
|
+
# === LLM Profiles ===
|
22
|
+
# Define LLM configurations for each agent type
|
23
|
+
llm_profiles:
|
24
|
+
# Manager: Plans and reasons about task progress
|
25
|
+
manager:
|
26
|
+
provider: GoogleGenAI
|
27
|
+
model: models/gemini-2.5-pro
|
28
|
+
temperature: 0.2
|
29
|
+
# kwargs: # optional kwargs, add api_key in kwargs if not already in .env
|
30
|
+
# max_tokens: 8192
|
31
|
+
|
32
|
+
# Executor: Selects and executes atomic actions
|
33
|
+
executor:
|
34
|
+
provider: GoogleGenAI
|
35
|
+
model: models/gemini-2.5-pro
|
36
|
+
temperature: 0.1
|
37
|
+
# kwargs:
|
38
|
+
# max_tokens: 4096
|
39
|
+
|
40
|
+
# CodeAct: Generates and executes code actions
|
41
|
+
codeact:
|
42
|
+
provider: GoogleGenAI
|
43
|
+
model: models/gemini-2.5-pro
|
44
|
+
temperature: 0.2
|
45
|
+
# kwargs:
|
46
|
+
# max_tokens: 8192
|
47
|
+
|
48
|
+
# Text Manipulator: Edits text in input fields
|
49
|
+
text_manipulator:
|
50
|
+
provider: GoogleGenAI
|
51
|
+
model: models/gemini-2.5-flash
|
52
|
+
temperature: 0.3
|
53
|
+
# kwargs:
|
54
|
+
# max_tokens: 4096
|
55
|
+
|
56
|
+
# App Opener: Opens apps by name/description
|
57
|
+
app_opener:
|
58
|
+
provider: GoogleGenAI
|
59
|
+
model: models/gemini-2.5-flash
|
60
|
+
temperature: 0.0
|
61
|
+
# kwargs:
|
62
|
+
# max_tokens: 512
|
63
|
+
|
64
|
+
# === Device Settings ===
|
65
|
+
device:
|
66
|
+
# Default device serial (null = auto-detect)
|
67
|
+
serial: null
|
68
|
+
# Use TCP communication instead of usb
|
69
|
+
use_tcp: false
|
70
|
+
|
71
|
+
# === Telemetry Settings ===
|
72
|
+
telemetry:
|
73
|
+
# Enable anonymous telemetry
|
74
|
+
enabled: false
|
75
|
+
|
76
|
+
# === Tracing Settings ===
|
77
|
+
tracing:
|
78
|
+
# Enable Arize Phoenix tracing
|
79
|
+
enabled: false
|
80
|
+
|
81
|
+
# === Logging Settings ===
|
82
|
+
logging:
|
83
|
+
# Enable debug logging
|
84
|
+
debug: true
|
85
|
+
# Trajectory saving level (none, step, action)
|
86
|
+
save_trajectory: none
|
87
|
+
|
88
|
+
# === Tool Settings ===
|
89
|
+
tools:
|
90
|
+
# Enable drag tool
|
91
|
+
allow_drag: false # this does nothing now place holder for now
|
@@ -5,13 +5,12 @@ DroidRun - A framework for controlling Android devices through LLM agents.
|
|
5
5
|
__version__ = "0.3.0"
|
6
6
|
|
7
7
|
# Import main classes for easier access
|
8
|
-
from droidrun.agent.utils.llm_picker import load_llm
|
9
|
-
from droidrun.tools import Tools, AdbTools, IOSTools
|
10
8
|
from droidrun.agent.droid import DroidAgent
|
9
|
+
from droidrun.agent.utils.llm_picker import load_llm
|
11
10
|
|
12
11
|
# Import macro functionality
|
13
12
|
from droidrun.macro import MacroPlayer, replay_macro_file, replay_macro_folder
|
14
|
-
|
13
|
+
from droidrun.tools import AdbTools, IOSTools, Tools
|
15
14
|
|
16
15
|
# Make main components available at package level
|
17
16
|
__all__ = [
|
@@ -1,8 +1,5 @@
|
|
1
1
|
from droidrun.agent.codeact.codeact_agent import CodeActAgent
|
2
|
-
from droidrun.agent.codeact.prompts import
|
3
|
-
DEFAULT_CODE_ACT_USER_PROMPT,
|
4
|
-
DEFAULT_NO_THOUGHTS_PROMPT
|
5
|
-
)
|
2
|
+
from droidrun.agent.codeact.prompts import DEFAULT_CODE_ACT_USER_PROMPT, DEFAULT_NO_THOUGHTS_PROMPT
|
6
3
|
|
7
4
|
__all__ = [
|
8
5
|
"CodeActAgent",
|
@@ -1,37 +1,37 @@
|
|
1
|
+
import asyncio
|
2
|
+
import json
|
1
3
|
import logging
|
2
4
|
import re
|
3
5
|
import time
|
4
|
-
import
|
5
|
-
|
6
|
-
import os
|
7
|
-
from typing import List, Optional, Tuple, Union
|
6
|
+
from typing import List, Union
|
7
|
+
|
8
8
|
from llama_index.core.base.llms.types import ChatMessage, ChatResponse
|
9
|
-
from llama_index.core.prompts import PromptTemplate
|
10
9
|
from llama_index.core.llms.llm import LLM
|
11
|
-
from llama_index.core.workflow import Workflow, StartEvent, StopEvent, Context, step
|
12
10
|
from llama_index.core.memory import Memory
|
11
|
+
from llama_index.core.prompts import PromptTemplate
|
12
|
+
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
|
13
|
+
|
13
14
|
from droidrun.agent.codeact.events import (
|
14
|
-
|
15
|
+
EpisodicMemoryEvent,
|
15
16
|
TaskEndEvent,
|
16
17
|
TaskExecutionEvent,
|
17
18
|
TaskExecutionResultEvent,
|
19
|
+
TaskInputEvent,
|
18
20
|
TaskThinkingEvent,
|
19
|
-
EpisodicMemoryEvent,
|
20
21
|
)
|
21
|
-
from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
|
22
|
-
from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
|
23
|
-
from droidrun.agent.usage import get_usage_from_response
|
24
|
-
from droidrun.agent.utils import chat_utils
|
25
|
-
from droidrun.agent.utils.executer import SimpleCodeExecutor
|
26
22
|
from droidrun.agent.codeact.prompts import (
|
27
23
|
DEFAULT_CODE_ACT_USER_PROMPT,
|
28
24
|
DEFAULT_NO_THOUGHTS_PROMPT,
|
29
25
|
)
|
30
|
-
|
26
|
+
from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
|
27
|
+
from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
|
28
|
+
from droidrun.agent.context.agent_persona import AgentPersona
|
31
29
|
from droidrun.agent.context.episodic_memory import EpisodicMemory, EpisodicMemoryStep
|
30
|
+
from droidrun.agent.usage import get_usage_from_response
|
31
|
+
from droidrun.agent.utils import chat_utils
|
32
|
+
from droidrun.agent.utils.executer import SimpleCodeExecutor
|
33
|
+
from droidrun.agent.utils.tools import ATOMIC_ACTION_SIGNATURES, get_atomic_tool_descriptions, build_custom_tool_descriptions
|
32
34
|
from droidrun.tools import Tools
|
33
|
-
from typing import Optional, Dict, Tuple, List, Any, Callable
|
34
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
35
35
|
|
36
36
|
logger = logging.getLogger("droidrun")
|
37
37
|
|
@@ -49,8 +49,8 @@ class CodeActAgent(Workflow):
|
|
49
49
|
persona: AgentPersona,
|
50
50
|
vision: bool,
|
51
51
|
tools_instance: "Tools",
|
52
|
-
all_tools_list: Dict[str, Callable[..., Any]],
|
53
52
|
max_steps: int = 5,
|
53
|
+
custom_tools: dict = None,
|
54
54
|
debug: bool = False,
|
55
55
|
*args,
|
56
56
|
**kwargs,
|
@@ -78,13 +78,40 @@ class CodeActAgent(Workflow):
|
|
78
78
|
|
79
79
|
self.tools = tools_instance
|
80
80
|
|
81
|
+
# Merge custom_tools with ATOMIC_ACTION_SIGNATURES
|
82
|
+
# Custom tools are treated the same as atomic actions by CodeAct
|
83
|
+
merged_signatures = {**ATOMIC_ACTION_SIGNATURES, **(custom_tools or {})}
|
84
|
+
|
85
|
+
# Build tool_list from merged signatures
|
81
86
|
self.tool_list = {}
|
87
|
+
for action_name, signature in merged_signatures.items():
|
88
|
+
func = signature["function"]
|
89
|
+
# Create bound function (curry tools_instance as first argument)
|
90
|
+
# Handle both sync and async functions
|
91
|
+
if asyncio.iscoroutinefunction(func):
|
92
|
+
async def make_async_bound(f, ti):
|
93
|
+
async def bound_func(*args, **kwargs):
|
94
|
+
return await f(ti, *args, **kwargs)
|
95
|
+
return bound_func
|
96
|
+
self.tool_list[action_name] = asyncio.run(make_async_bound(func, tools_instance))
|
97
|
+
else:
|
98
|
+
self.tool_list[action_name] = lambda *args, f=func, ti=tools_instance: f(ti, *args)
|
99
|
+
|
100
|
+
# Add non-atomic tools (remember, complete) from tools_instance
|
101
|
+
self.tool_list["remember"] = tools_instance.remember
|
102
|
+
self.tool_list["complete"] = tools_instance.complete
|
82
103
|
|
83
|
-
|
84
|
-
|
85
|
-
self.tool_list[tool_name] = all_tools_list[tool_name]
|
104
|
+
# Get tool descriptions from ATOMIC_ACTION_SIGNATURES and custom_tools
|
105
|
+
self.tool_descriptions = get_atomic_tool_descriptions()
|
86
106
|
|
87
|
-
|
107
|
+
# Add custom tool descriptions if provided
|
108
|
+
custom_descriptions = build_custom_tool_descriptions(custom_tools or {})
|
109
|
+
if custom_descriptions:
|
110
|
+
self.tool_descriptions += "\n" + custom_descriptions
|
111
|
+
|
112
|
+
# Add descriptions for remember/complete
|
113
|
+
self.tool_descriptions += "\n- remember(information: str): Remember information for later use"
|
114
|
+
self.tool_descriptions += "\n- complete(success: bool, reason: str): Mark task as complete"
|
88
115
|
|
89
116
|
self.system_prompt_content = persona.system_prompt.format(
|
90
117
|
tool_descriptions=self.tool_descriptions
|
@@ -162,7 +189,7 @@ class CodeActAgent(Workflow):
|
|
162
189
|
logger.info(f"🧠 Step {self.steps_counter}: Thinking...")
|
163
190
|
|
164
191
|
model = self.llm.class_name()
|
165
|
-
|
192
|
+
|
166
193
|
if "remember" in self.tool_list and self.remembered_info:
|
167
194
|
await ctx.store.set("remembered_info", self.remembered_info)
|
168
195
|
chat_history = await chat_utils.add_memory_block(self.remembered_info, chat_history)
|
@@ -178,7 +205,7 @@ class CodeActAgent(Workflow):
|
|
178
205
|
logger.warning(
|
179
206
|
"[yellow]DeepSeek doesnt support images. Disabling screenshots[/]"
|
180
207
|
)
|
181
|
-
elif self.vision
|
208
|
+
elif self.vision: # if vision is enabled, add screenshot to chat history
|
182
209
|
chat_history = await chat_utils.add_screenshot_image_block(screenshot, chat_history)
|
183
210
|
|
184
211
|
if context == "ui_state":
|
@@ -190,8 +217,8 @@ class CodeActAgent(Workflow):
|
|
190
217
|
state["a11y_tree"], chat_history
|
191
218
|
)
|
192
219
|
chat_history = await chat_utils.add_phone_state_block(state["phone_state"], chat_history)
|
193
|
-
except Exception
|
194
|
-
logger.warning(
|
220
|
+
except Exception:
|
221
|
+
logger.warning("⚠️ Error retrieving state from the connected device. Is the Accessibility Service enabled?")
|
195
222
|
|
196
223
|
|
197
224
|
if context == "packages":
|
@@ -254,7 +281,7 @@ class CodeActAgent(Workflow):
|
|
254
281
|
"""Execute the code and return the result."""
|
255
282
|
code = ev.code
|
256
283
|
assert code, "Code cannot be empty."
|
257
|
-
logger.info(
|
284
|
+
logger.info("⚡ Executing action...")
|
258
285
|
logger.info(f"Code to execute:\n```python\n{code}\n```")
|
259
286
|
|
260
287
|
try:
|
@@ -269,16 +296,16 @@ class CodeActAgent(Workflow):
|
|
269
296
|
for ui_state in ui_states[:-1]:
|
270
297
|
ctx.write_event_to_stream(RecordUIStateEvent(ui_state=ui_state['a11y_tree']))
|
271
298
|
|
272
|
-
if self.tools.finished
|
299
|
+
if self.tools.finished:
|
273
300
|
logger.debug(" - Task completed.")
|
274
301
|
event = TaskEndEvent(
|
275
302
|
success=self.tools.success, reason=self.tools.reason
|
276
303
|
)
|
277
304
|
ctx.write_event_to_stream(event)
|
278
305
|
return event
|
279
|
-
|
306
|
+
|
280
307
|
self.remembered_info = self.tools.memory
|
281
|
-
|
308
|
+
|
282
309
|
event = TaskExecutionResultEvent(output=str(result['output']))
|
283
310
|
ctx.write_event_to_stream(event)
|
284
311
|
return event
|
@@ -323,11 +350,11 @@ class CodeActAgent(Workflow):
|
|
323
350
|
"""Finalize the workflow."""
|
324
351
|
self.tools.finished = False
|
325
352
|
await ctx.store.set("chat_memory", self.chat_memory)
|
326
|
-
|
353
|
+
|
327
354
|
# Add final state observation to episodic memory
|
328
355
|
if self.vision:
|
329
356
|
await self._add_final_state_observation(ctx)
|
330
|
-
|
357
|
+
|
331
358
|
result = {}
|
332
359
|
result.update(
|
333
360
|
{
|
@@ -403,7 +430,7 @@ class CodeActAgent(Workflow):
|
|
403
430
|
logger.error(f"Rate limit error. Retrying in {seconds} seconds...")
|
404
431
|
time.sleep(seconds)
|
405
432
|
else:
|
406
|
-
logger.error(
|
433
|
+
logger.error("Rate limit error. Retrying in 5 seconds...")
|
407
434
|
time.sleep(40)
|
408
435
|
logger.debug("🔍 Retrying call to LLM...")
|
409
436
|
response = await self.llm.achat(messages=messages_to_send)
|
@@ -452,26 +479,25 @@ class CodeActAgent(Workflow):
|
|
452
479
|
try:
|
453
480
|
# Get current screenshot and UI state
|
454
481
|
screenshot = None
|
455
|
-
|
456
|
-
|
482
|
+
|
457
483
|
try:
|
458
484
|
_, screenshot_bytes = self.tools.take_screenshot()
|
459
485
|
screenshot = screenshot_bytes
|
460
486
|
except Exception as e:
|
461
487
|
logger.warning(f"Failed to capture final screenshot: {e}")
|
462
|
-
|
488
|
+
|
463
489
|
try:
|
464
490
|
(a11y_tree, phone_state) = self.tools.get_state()
|
465
491
|
except Exception as e:
|
466
492
|
logger.warning(f"Failed to capture final UI state: {e}")
|
467
|
-
|
493
|
+
|
468
494
|
# Create final observation chat history and response
|
469
495
|
final_chat_history = [{"role": "system", "content": "Final state observation after task completion"}]
|
470
496
|
final_response = {
|
471
|
-
"role": "user",
|
497
|
+
"role": "user",
|
472
498
|
"content": f"Final State Observation:\nUI State: {a11y_tree}\nScreenshot: {'Available' if screenshot else 'Not available'}"
|
473
499
|
}
|
474
|
-
|
500
|
+
|
475
501
|
# Create final episodic memory step
|
476
502
|
final_step = EpisodicMemoryStep(
|
477
503
|
chat_history=json.dumps(final_chat_history),
|
@@ -479,9 +505,9 @@ class CodeActAgent(Workflow):
|
|
479
505
|
timestamp=time.time(),
|
480
506
|
screenshot=screenshot
|
481
507
|
)
|
482
|
-
|
508
|
+
|
483
509
|
self.episodic_memory.steps.append(final_step)
|
484
510
|
logger.info("Added final state observation to episodic memory")
|
485
|
-
|
511
|
+
|
486
512
|
except Exception as e:
|
487
513
|
logger.error(f"Failed to add final state observation: {e}")
|
@@ -1,10 +1,13 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
1
3
|
from llama_index.core.llms import ChatMessage
|
2
4
|
from llama_index.core.workflow import Event
|
3
|
-
from typing import Optional
|
4
5
|
|
5
6
|
from droidrun.agent.usage import UsageResult
|
7
|
+
|
6
8
|
from ..context.episodic_memory import EpisodicMemory
|
7
9
|
|
10
|
+
|
8
11
|
class TaskInputEvent(Event):
|
9
12
|
input: list[ChatMessage]
|
10
13
|
|
@@ -12,7 +15,7 @@ class TaskInputEvent(Event):
|
|
12
15
|
|
13
16
|
class TaskThinkingEvent(Event):
|
14
17
|
thoughts: Optional[str] = None
|
15
|
-
code: Optional[str] = None
|
18
|
+
code: Optional[str] = None
|
16
19
|
usage: Optional[UsageResult] = None
|
17
20
|
|
18
21
|
class TaskExecutionEvent(Event):
|
@@ -28,4 +31,4 @@ class TaskEndEvent(Event):
|
|
28
31
|
reason: str
|
29
32
|
|
30
33
|
class EpisodicMemoryEvent(Event):
|
31
|
-
episodic_memory: EpisodicMemory
|
34
|
+
episodic_memory: EpisodicMemory
|
@@ -1,5 +1,7 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from llama_index.core.workflow import Event
|
2
|
-
|
4
|
+
|
3
5
|
|
4
6
|
class ScreenshotEvent(Event):
|
5
7
|
screenshot: bytes
|
@@ -16,7 +18,7 @@ class TapActionEvent(MacroEvent):
|
|
16
18
|
element_index: int = None
|
17
19
|
element_text: str = ""
|
18
20
|
element_bounds: str = ""
|
19
|
-
|
21
|
+
|
20
22
|
class SwipeActionEvent(MacroEvent):
|
21
23
|
"""Event for swipe actions with coordinates"""
|
22
24
|
start_x: int
|
@@ -9,15 +9,13 @@ This module contains:
|
|
9
9
|
from .agent_persona import AgentPersona
|
10
10
|
from .context_injection_manager import ContextInjectionManager
|
11
11
|
from .episodic_memory import EpisodicMemory, EpisodicMemoryStep
|
12
|
-
from .
|
13
|
-
from .task_manager import TaskManager, Task
|
12
|
+
from .task_manager import Task, TaskManager
|
14
13
|
|
15
14
|
__all__ = [
|
16
15
|
"AgentPersona",
|
17
16
|
"ContextInjectionManager",
|
18
17
|
"EpisodicMemory",
|
19
18
|
"EpisodicMemoryStep",
|
20
|
-
"Reflection",
|
21
19
|
"TaskManager",
|
22
20
|
"Task"
|
23
21
|
]
|
@@ -5,12 +5,12 @@ This module provides the ContextInjectionManager class that manages different ag
|
|
5
5
|
each with specific system prompts, contexts, and tool subsets tailored for specialized tasks.
|
6
6
|
"""
|
7
7
|
|
8
|
-
import logging
|
9
|
-
from typing import Optional, List
|
10
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
11
8
|
#import chromadb
|
12
9
|
import json
|
13
|
-
|
10
|
+
import logging
|
11
|
+
from typing import List, Optional
|
12
|
+
|
13
|
+
from droidrun.agent.context.agent_persona import AgentPersona
|
14
14
|
|
15
15
|
logger = logging.getLogger("droidrun")
|
16
16
|
|
@@ -59,8 +59,8 @@ class ContextInjectionManager:
|
|
59
59
|
Returns:
|
60
60
|
AgentPersona instance or None if not found
|
61
61
|
"""
|
62
|
-
|
62
|
+
|
63
63
|
return self.personas.get(agent_type)
|
64
|
-
|
64
|
+
|
65
65
|
def get_all_personas(self) -> List[str]:
|
66
66
|
return self.personas
|
@@ -1,7 +1,9 @@
|
|
1
1
|
from dataclasses import dataclass, field
|
2
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
3
2
|
from typing import List, Optional
|
4
3
|
|
4
|
+
from droidrun.agent.context.agent_persona import AgentPersona
|
5
|
+
|
6
|
+
|
5
7
|
@dataclass
|
6
8
|
class EpisodicMemoryStep:
|
7
9
|
chat_history: str
|
@@ -9,7 +11,7 @@ class EpisodicMemoryStep:
|
|
9
11
|
timestamp: float
|
10
12
|
screenshot: Optional[bytes]
|
11
13
|
|
12
|
-
@dataclass
|
14
|
+
@dataclass
|
13
15
|
class EpisodicMemory:
|
14
16
|
persona: AgentPersona
|
15
|
-
steps: List[EpisodicMemoryStep] = field(default_factory=list)
|
17
|
+
steps: List[EpisodicMemoryStep] = field(default_factory=list)
|
@@ -1,11 +1,11 @@
|
|
1
|
-
from .default import DEFAULT
|
2
|
-
from .ui_expert import UI_EXPERT
|
3
1
|
from .app_starter import APP_STARTER_EXPERT
|
4
2
|
from .big_agent import BIG_AGENT
|
3
|
+
from .default import DEFAULT
|
4
|
+
from .ui_expert import UI_EXPERT
|
5
5
|
|
6
6
|
__all__ = [
|
7
7
|
'DEFAULT',
|
8
8
|
'UI_EXPERT',
|
9
9
|
'APP_STARTER_EXPERT',
|
10
10
|
'BIG_AGENT',
|
11
|
-
]
|
11
|
+
]
|
@@ -2,7 +2,7 @@ from droidrun.agent.context.agent_persona import AgentPersona
|
|
2
2
|
from droidrun.tools import Tools
|
3
3
|
|
4
4
|
APP_STARTER_EXPERT = AgentPersona(
|
5
|
-
name="AppStarterExpert",
|
5
|
+
name="AppStarterExpert",
|
6
6
|
description="Specialized in app launching",
|
7
7
|
expertise_areas=[
|
8
8
|
"app launching"
|
@@ -37,8 +37,8 @@ APP_STARTER_EXPERT = AgentPersona(
|
|
37
37
|
In addition to the Python Standard Library and any functions you have already written, you can use the following functions:
|
38
38
|
{tool_descriptions}
|
39
39
|
|
40
|
-
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
40
|
+
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
41
41
|
|
42
42
|
You focus ONLY on app launching and package management - UI interactions within apps are handled by UI specialists.""",
|
43
43
|
|
44
|
-
)
|
44
|
+
)
|
@@ -5,7 +5,7 @@ BIG_AGENT = AgentPersona(
|
|
5
5
|
name="Big Agent",
|
6
6
|
description="Big Agent. Use this as your Big Agent",
|
7
7
|
expertise_areas=[
|
8
|
-
"UI navigation", "button interactions", "text input",
|
8
|
+
"UI navigation", "button interactions", "text input",
|
9
9
|
"menu navigation", "form filling", "scrolling", "app launching"
|
10
10
|
],
|
11
11
|
allowed_tools=[
|
@@ -90,7 +90,7 @@ BIG_AGENT = AgentPersona(
|
|
90
90
|
- Present the results clearly and concisely as if you computed them directly
|
91
91
|
- Structure your response like you're directly answering the user's query, not explaining how you solved it
|
92
92
|
|
93
|
-
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
93
|
+
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
94
94
|
"""
|
95
95
|
|
96
|
-
)
|
96
|
+
)
|