droidrun 0.3.4__tar.gz → 0.3.6__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.4 → droidrun-0.3.6}/.github/workflows/bounty.yml +2 -2
- {droidrun-0.3.4 → droidrun-0.3.6}/PKG-INFO +17 -23
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/docs.json +1 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/quickstart.mdx +3 -2
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/sdk/droid-agent.mdx +1 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/codeact/codeact_agent.py +16 -3
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/codeact/events.py +3 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/common/events.py +5 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/task_manager.py +10 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/droid/droid_agent.py +137 -84
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/planner/events.py +2 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/planner/planner_agent.py +18 -7
- droidrun-0.3.6/droidrun/agent/usage.py +213 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/chat_utils.py +24 -22
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/executer.py +1 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/llm_picker.py +91 -54
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/trajectory.py +256 -154
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/cli/logs.py +4 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/cli/main.py +3 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/portal.py +20 -7
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/telemetry/events.py +1 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/tools/adb.py +99 -167
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/tools/tools.py +0 -1
- {droidrun-0.3.4 → droidrun-0.3.6}/pyproject.toml +27 -23
- {droidrun-0.3.4 → droidrun-0.3.6}/.github/workflows/publish.yml +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/.gitignore +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/CHANGELOG.md +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/CONTRIBUTING.md +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/LICENSE +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/MANIFEST.in +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/README.md +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/.generated-files.txt +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/favicon.png +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/logo/dark.svg +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/logo/light.svg +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v1/concepts/agent.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v1/concepts/android-control.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v1/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v1/overview.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v1/quickstart.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/concepts/agent.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/concepts/android-control.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/concepts/planning.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/concepts/tracing.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/overview.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v2/quickstart.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/concepts/agent.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/concepts/android-tools.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/concepts/models.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/concepts/portal-app.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/cli.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/gemini.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/ollama.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/openailike.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/overview.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/guides/telemetry.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/images/portal_apk.png +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/overview.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/sdk/adb-tools.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/sdk/base-tools.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/docs/v3/sdk/ios-tools.mdx +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/__main__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/codeact/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/codeact/prompts.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/common/default.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/agent_persona.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/context_injection_manager.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/episodic_memory.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/personas/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/personas/app_starter.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/personas/big_agent.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/personas/default.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/personas/ui_expert.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/context/reflection.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/droid/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/droid/events.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/oneflows/reflector.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/planner/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/planner/prompts.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/agent/utils/async_utils.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/cli/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/macro/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/macro/__main__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/macro/cli.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/macro/replay.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/telemetry/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/telemetry/tracker.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/tools/__init__.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/droidrun/tools/ios.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/gen-docs-sdk-ref.sh +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/setup.py +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/static/droidrun-dark.png +0 -0
- {droidrun-0.3.4 → droidrun-0.3.6}/static/droidrun.png +0 -0
@@ -64,7 +64,7 @@ jobs:
|
|
64
64
|
eligible) OPT_NAME="📝 Eligible" ;;
|
65
65
|
bounty-official) OPT_NAME="💰 Bounty" ;;
|
66
66
|
claimed) OPT_NAME="🛠️ In Progress" ;;
|
67
|
-
*) echo "No matching status for $LABEL"; exit
|
67
|
+
*) echo "No matching status for $LABEL"; exit 78 ;;
|
68
68
|
esac
|
69
69
|
|
70
70
|
# extract from JSON map
|
@@ -131,4 +131,4 @@ jobs:
|
|
131
131
|
-f proj="${PROJECT_ID}" \
|
132
132
|
-f item="${ITEM_ID}" \
|
133
133
|
-f field="${STATUS_FIELD_ID}" \
|
134
|
-
-f opt="${OPTION_ID}"
|
134
|
+
-f opt="${OPTION_ID}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: droidrun
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.6
|
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
|
@@ -26,32 +26,26 @@ Classifier: Topic :: Software Development :: Testing :: Acceptance
|
|
26
26
|
Classifier: Topic :: System :: Emulators
|
27
27
|
Classifier: Topic :: Utilities
|
28
28
|
Requires-Python: >=3.11
|
29
|
-
Requires-Dist: adbutils
|
30
|
-
Requires-Dist:
|
31
|
-
Requires-Dist: anthropic>=0.7.0
|
29
|
+
Requires-Dist: adbutils>=2.10.2
|
30
|
+
Requires-Dist: anthropic>=0.67.0
|
32
31
|
Requires-Dist: apkutils==2.0.0
|
33
|
-
Requires-Dist:
|
34
|
-
Requires-Dist:
|
35
|
-
Requires-Dist: llama-index
|
36
|
-
Requires-Dist: llama-index-
|
37
|
-
Requires-Dist: llama-index-llms-
|
38
|
-
Requires-Dist: llama-index-llms-
|
39
|
-
Requires-Dist: llama-index
|
40
|
-
Requires-Dist:
|
41
|
-
Requires-Dist:
|
42
|
-
Requires-Dist:
|
43
|
-
Requires-Dist:
|
44
|
-
Requires-Dist: pillow>=10.0.0
|
45
|
-
Requires-Dist: posthog==6.0.2
|
46
|
-
Requires-Dist: pydantic>=2.0.0
|
47
|
-
Requires-Dist: python-dotenv>=1.0.0
|
48
|
-
Requires-Dist: rich>=13.0.0
|
32
|
+
Requires-Dist: llama-index-llms-anthropic>=0.8.6
|
33
|
+
Requires-Dist: llama-index-llms-deepseek>=0.2.1
|
34
|
+
Requires-Dist: llama-index-llms-google-genai>=0.3.1
|
35
|
+
Requires-Dist: llama-index-llms-ollama>=0.7.2
|
36
|
+
Requires-Dist: llama-index-llms-openai-like>=0.5.1
|
37
|
+
Requires-Dist: llama-index-llms-openai>=0.5.6
|
38
|
+
Requires-Dist: llama-index>=0.14.0
|
39
|
+
Requires-Dist: openai>=1.107.1
|
40
|
+
Requires-Dist: posthog>=6.7.4
|
41
|
+
Requires-Dist: pydantic>=2.11.7
|
42
|
+
Requires-Dist: rich>=14.1.0
|
49
43
|
Provides-Extra: dev
|
50
|
-
Requires-Dist: bandit>=1.
|
44
|
+
Requires-Dist: bandit>=1.8.6; extra == 'dev'
|
51
45
|
Requires-Dist: black>=23.0.0; extra == 'dev'
|
52
46
|
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
53
|
-
Requires-Dist: ruff>=0.
|
54
|
-
Requires-Dist: safety>=2.
|
47
|
+
Requires-Dist: ruff>=0.13.0; extra == 'dev'
|
48
|
+
Requires-Dist: safety>=3.2.11; extra == 'dev'
|
55
49
|
Description-Content-Type: text/markdown
|
56
50
|
|
57
51
|
<picture>
|
@@ -26,8 +26,9 @@ Before installing DroidRun, ensure you have:
|
|
26
26
|
- Connected via USB or on the same network (for wireless debugging)
|
27
27
|
|
28
28
|
### Install from PyPI
|
29
|
+
Use [`uv`](https://docs.astral.sh/uv/getting-started/installation/)
|
29
30
|
```bash
|
30
|
-
pip install droidrun
|
31
|
+
uv pip install droidrun
|
31
32
|
```
|
32
33
|
|
33
34
|
### Setup the Portal APK
|
@@ -91,4 +92,4 @@ Now that you've got DroidRun running, you can:
|
|
91
92
|
- Learn about the [Agent](/v3/concepts/agent)
|
92
93
|
- See supported [LLM providers](/v3/concepts/models)
|
93
94
|
- Discover [Android interactions](/v3/concepts/android-control)
|
94
|
-
- Learn about the [Portal App](/v3/concepts/portal-app)
|
95
|
+
- Learn about the [Portal App](/v3/concepts/portal-app)
|
@@ -18,7 +18,8 @@ from droidrun.agent.codeact.events import (
|
|
18
18
|
TaskThinkingEvent,
|
19
19
|
EpisodicMemoryEvent,
|
20
20
|
)
|
21
|
-
from droidrun.agent.common.events import ScreenshotEvent
|
21
|
+
from droidrun.agent.common.events import ScreenshotEvent, RecordUIStateEvent
|
22
|
+
from droidrun.agent.usage import get_usage_from_response
|
22
23
|
from droidrun.agent.utils import chat_utils
|
23
24
|
from droidrun.agent.utils.executer import SimpleCodeExecutor
|
24
25
|
from droidrun.agent.codeact.prompts import (
|
@@ -182,6 +183,7 @@ class CodeActAgent(Workflow):
|
|
182
183
|
try:
|
183
184
|
state = self.tools.get_state()
|
184
185
|
await ctx.set("ui_state", state["a11y_tree"])
|
186
|
+
ctx.write_event_to_stream(RecordUIStateEvent(ui_state=state["a11y_tree"]))
|
185
187
|
chat_history = await chat_utils.add_ui_text_block(
|
186
188
|
state["a11y_tree"], chat_history
|
187
189
|
)
|
@@ -202,11 +204,17 @@ class CodeActAgent(Workflow):
|
|
202
204
|
success=False, reason="LLM response is None. This is a critical error."
|
203
205
|
)
|
204
206
|
|
207
|
+
try:
|
208
|
+
usage = get_usage_from_response(self.llm.class_name(), response)
|
209
|
+
except Exception as e:
|
210
|
+
logger.warning(f"Could not get llm usage from response: {e}")
|
211
|
+
usage = None
|
212
|
+
|
205
213
|
await self.chat_memory.aput(response.message)
|
206
214
|
|
207
215
|
code, thoughts = chat_utils.extract_code_and_thought(response.message.content)
|
208
216
|
|
209
|
-
event = TaskThinkingEvent(thoughts=thoughts, code=code)
|
217
|
+
event = TaskThinkingEvent(thoughts=thoughts, code=code, usage=usage)
|
210
218
|
ctx.write_event_to_stream(event)
|
211
219
|
return event
|
212
220
|
|
@@ -255,6 +263,10 @@ class CodeActAgent(Workflow):
|
|
255
263
|
for screenshot in screenshots[:-1]: # the last screenshot will be captured by next step
|
256
264
|
ctx.write_event_to_stream(ScreenshotEvent(screenshot=screenshot))
|
257
265
|
|
266
|
+
ui_states = result['ui_states']
|
267
|
+
for ui_state in ui_states[:-1]:
|
268
|
+
ctx.write_event_to_stream(RecordUIStateEvent(ui_state=ui_state['a11y_tree']))
|
269
|
+
|
258
270
|
if self.tools.finished == True:
|
259
271
|
logger.debug(" - Task completed.")
|
260
272
|
event = TaskEndEvent(
|
@@ -311,7 +323,8 @@ class CodeActAgent(Workflow):
|
|
311
323
|
await ctx.set("chat_memory", self.chat_memory)
|
312
324
|
|
313
325
|
# Add final state observation to episodic memory
|
314
|
-
|
326
|
+
if self.vision:
|
327
|
+
await self._add_final_state_observation(ctx)
|
315
328
|
|
316
329
|
result = {}
|
317
330
|
result.update(
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from llama_index.core.llms import ChatMessage
|
2
2
|
from llama_index.core.workflow import Event
|
3
3
|
from typing import Optional
|
4
|
+
|
5
|
+
from droidrun.agent.usage import UsageResult
|
4
6
|
from ..context.episodic_memory import EpisodicMemory
|
5
7
|
|
6
8
|
class TaskInputEvent(Event):
|
@@ -11,6 +13,7 @@ class TaskInputEvent(Event):
|
|
11
13
|
class TaskThinkingEvent(Event):
|
12
14
|
thoughts: Optional[str] = None
|
13
15
|
code: Optional[str] = None
|
16
|
+
usage: Optional[UsageResult] = None
|
14
17
|
|
15
18
|
class TaskExecutionEvent(Event):
|
16
19
|
code: str
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from llama_index.core.workflow import Event
|
2
|
+
from typing import Dict, Any
|
2
3
|
|
3
4
|
class ScreenshotEvent(Event):
|
4
5
|
screenshot: bytes
|
@@ -44,4 +45,7 @@ class KeyPressActionEvent(MacroEvent):
|
|
44
45
|
class StartAppEvent(MacroEvent):
|
45
46
|
""""Event for starting an app"""
|
46
47
|
package: str
|
47
|
-
activity: str = None
|
48
|
+
activity: str = None
|
49
|
+
|
50
|
+
class RecordUIStateEvent(Event):
|
51
|
+
ui_state: list[Dict[str, Any]]
|
@@ -43,6 +43,13 @@ class TaskManager:
|
|
43
43
|
def get_task_history(self):
|
44
44
|
return self.task_history
|
45
45
|
|
46
|
+
def get_current_task(self) -> Optional[Task]:
|
47
|
+
"""Return the first task with status "pending" from the task list."""
|
48
|
+
for task in self.tasks:
|
49
|
+
if task.status == self.STATUS_PENDING:
|
50
|
+
return task
|
51
|
+
return None
|
52
|
+
|
46
53
|
def complete_task(self, task: Task, message: Optional[str] = None):
|
47
54
|
task = copy.deepcopy(task)
|
48
55
|
task.status = self.STATUS_COMPLETED
|
@@ -60,6 +67,9 @@ class TaskManager:
|
|
60
67
|
|
61
68
|
def get_failed_tasks(self) -> list[dict]:
|
62
69
|
return [task for task in self.task_history if task.status == self.STATUS_FAILED]
|
70
|
+
|
71
|
+
def get_task_history(self) -> list[dict]:
|
72
|
+
return self.task_history
|
63
73
|
|
64
74
|
|
65
75
|
def save_to_file(self):
|