droidrun 0.3.10.dev3__py3-none-any.whl → 0.3.10.dev5__py3-none-any.whl
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/agent/codeact/__init__.py +1 -4
- droidrun/agent/codeact/codeact_agent.py +95 -86
- droidrun/agent/codeact/events.py +1 -2
- droidrun/agent/context/__init__.py +5 -9
- droidrun/agent/context/episodic_memory.py +1 -3
- droidrun/agent/context/task_manager.py +8 -2
- droidrun/agent/droid/droid_agent.py +102 -141
- droidrun/agent/droid/events.py +45 -14
- droidrun/agent/executor/__init__.py +6 -4
- droidrun/agent/executor/events.py +29 -9
- droidrun/agent/executor/executor_agent.py +86 -28
- droidrun/agent/executor/prompts.py +8 -2
- droidrun/agent/manager/__init__.py +6 -7
- droidrun/agent/manager/events.py +16 -4
- droidrun/agent/manager/manager_agent.py +130 -69
- droidrun/agent/manager/prompts.py +1 -159
- droidrun/agent/utils/chat_utils.py +64 -2
- droidrun/agent/utils/device_state_formatter.py +54 -26
- droidrun/agent/utils/executer.py +66 -80
- droidrun/agent/utils/inference.py +11 -10
- droidrun/agent/utils/tools.py +58 -6
- droidrun/agent/utils/trajectory.py +18 -12
- droidrun/cli/logs.py +118 -56
- droidrun/cli/main.py +154 -136
- droidrun/config_manager/__init__.py +9 -7
- droidrun/config_manager/app_card_loader.py +148 -0
- droidrun/config_manager/config_manager.py +200 -102
- droidrun/config_manager/path_resolver.py +104 -0
- droidrun/config_manager/prompt_loader.py +75 -0
- droidrun/macro/__init__.py +1 -1
- droidrun/macro/cli.py +23 -18
- droidrun/telemetry/__init__.py +2 -2
- droidrun/telemetry/events.py +3 -3
- droidrun/telemetry/tracker.py +1 -1
- droidrun/tools/adb.py +1 -1
- droidrun/tools/ios.py +3 -2
- {droidrun-0.3.10.dev3.dist-info → droidrun-0.3.10.dev5.dist-info}/METADATA +10 -4
- droidrun-0.3.10.dev5.dist-info/RECORD +61 -0
- droidrun/agent/codeact/prompts.py +0 -26
- droidrun/agent/context/agent_persona.py +0 -16
- droidrun/agent/context/context_injection_manager.py +0 -66
- droidrun/agent/context/personas/__init__.py +0 -11
- droidrun/agent/context/personas/app_starter.py +0 -44
- droidrun/agent/context/personas/big_agent.py +0 -96
- droidrun/agent/context/personas/default.py +0 -95
- droidrun/agent/context/personas/ui_expert.py +0 -108
- droidrun/agent/planner/__init__.py +0 -13
- droidrun/agent/planner/events.py +0 -21
- droidrun/agent/planner/planner_agent.py +0 -311
- droidrun/agent/planner/prompts.py +0 -124
- droidrun-0.3.10.dev3.dist-info/RECORD +0 -70
- {droidrun-0.3.10.dev3.dist-info → droidrun-0.3.10.dev5.dist-info}/WHEEL +0 -0
- {droidrun-0.3.10.dev3.dist-info → droidrun-0.3.10.dev5.dist-info}/entry_points.txt +0 -0
- {droidrun-0.3.10.dev3.dist-info → droidrun-0.3.10.dev5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
"""
|
2
|
+
Prompt loading utility for markdown-based prompts.
|
3
|
+
|
4
|
+
Supports variable substitution with escape sequences:
|
5
|
+
- {variable} → replaced with value
|
6
|
+
- {{variable}} → literal {variable}
|
7
|
+
- Missing variables → left as {variable}
|
8
|
+
"""
|
9
|
+
|
10
|
+
import re
|
11
|
+
from pathlib import Path
|
12
|
+
from typing import Any, Dict
|
13
|
+
|
14
|
+
from droidrun.config_manager.path_resolver import PathResolver
|
15
|
+
|
16
|
+
|
17
|
+
class PromptLoader:
|
18
|
+
"""Load and format markdown prompts with variable substitution."""
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def load_prompt(path: str, variables: Dict[str, Any] = None) -> str:
|
22
|
+
"""
|
23
|
+
Load prompt from .md file and substitute variables.
|
24
|
+
|
25
|
+
Path resolution:
|
26
|
+
- Checks working directory first (for user overrides)
|
27
|
+
- Falls back to project directory (for default prompts)
|
28
|
+
- Example: "config/prompts/codeact/system.md"
|
29
|
+
|
30
|
+
Variable substitution:
|
31
|
+
- {variable} → replaced with value from variables dict
|
32
|
+
- {{variable}} → becomes literal {variable} in output
|
33
|
+
- Missing variables → left as {variable} (no error)
|
34
|
+
|
35
|
+
Args:
|
36
|
+
path: Path to prompt file (relative or absolute)
|
37
|
+
variables: Dict of variable names to values
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
Formatted prompt string
|
41
|
+
|
42
|
+
Raises:
|
43
|
+
FileNotFoundError: If prompt file doesn't exist
|
44
|
+
"""
|
45
|
+
# Resolve path (checks working dir, then project dir)
|
46
|
+
prompt_path = PathResolver.resolve(path, must_exist=True)
|
47
|
+
|
48
|
+
prompt_text = prompt_path.read_text(encoding="utf-8")
|
49
|
+
|
50
|
+
if variables is None:
|
51
|
+
return prompt_text
|
52
|
+
|
53
|
+
# Handle escaped braces: {{variable}} → {variable}
|
54
|
+
# Strategy: Replace {{...}} with placeholder, do substitution, restore
|
55
|
+
escaped_pattern = re.compile(r'\{\{([^}]+)\}\}')
|
56
|
+
placeholders = {}
|
57
|
+
counter = [0]
|
58
|
+
|
59
|
+
def escape_replacer(match):
|
60
|
+
placeholder = f"__ESCAPED_{counter[0]}__"
|
61
|
+
placeholders[placeholder] = "{" + match.group(1) + "}"
|
62
|
+
counter[0] += 1
|
63
|
+
return placeholder
|
64
|
+
|
65
|
+
prompt_text = escaped_pattern.sub(escape_replacer, prompt_text)
|
66
|
+
|
67
|
+
# Substitute variables
|
68
|
+
for key, value in variables.items():
|
69
|
+
prompt_text = prompt_text.replace(f"{{{key}}}", str(value))
|
70
|
+
|
71
|
+
# Restore escaped braces
|
72
|
+
for placeholder, original in placeholders.items():
|
73
|
+
prompt_text = prompt_text.replace(placeholder, original)
|
74
|
+
|
75
|
+
return prompt_text
|
droidrun/macro/__init__.py
CHANGED
@@ -5,7 +5,7 @@ This module provides functionality to replay macro sequences that were
|
|
5
5
|
recorded during DroidAgent execution.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from .replay import MacroPlayer, replay_macro_file, replay_macro_folder
|
8
|
+
from droidrun.macro.replay import MacroPlayer, replay_macro_file, replay_macro_folder
|
9
9
|
|
10
10
|
__all__ = [
|
11
11
|
"MacroPlayer",
|
droidrun/macro/cli.py
CHANGED
@@ -13,6 +13,7 @@ from rich.console import Console
|
|
13
13
|
from rich.table import Table
|
14
14
|
|
15
15
|
from droidrun.agent.utils.trajectory import Trajectory
|
16
|
+
from droidrun.config_manager.path_resolver import PathResolver
|
16
17
|
from droidrun.macro.replay import MacroPlayer
|
17
18
|
|
18
19
|
console = Console()
|
@@ -79,16 +80,19 @@ def replay(path: str, device: Optional[str], delay: float, start_from: int, max_
|
|
79
80
|
async def _replay_async(path: str, device: str, delay: float, start_from: int, max_steps: Optional[int], dry_run: bool, logger: logging.Logger):
|
80
81
|
"""Async function to handle macro replay."""
|
81
82
|
try:
|
82
|
-
|
83
|
-
|
83
|
+
# Resolve path (checks working dir, then project dir)
|
84
|
+
resolved_path = PathResolver.resolve(path, must_exist=True)
|
85
|
+
|
86
|
+
if resolved_path.is_file():
|
87
|
+
logger.info(f"📄 Loading macro from file: {resolved_path}")
|
84
88
|
player = MacroPlayer(device_serial=device, delay_between_actions=delay)
|
85
|
-
macro_data = player.load_macro_from_file(
|
86
|
-
elif
|
87
|
-
logger.info(f"📁 Loading macro from folder: {
|
89
|
+
macro_data = player.load_macro_from_file(str(resolved_path))
|
90
|
+
elif resolved_path.is_dir():
|
91
|
+
logger.info(f"📁 Loading macro from folder: {resolved_path}")
|
88
92
|
player = MacroPlayer(device_serial=device, delay_between_actions=delay)
|
89
|
-
macro_data = player.load_macro_from_folder(
|
93
|
+
macro_data = player.load_macro_from_folder(str(resolved_path))
|
90
94
|
else:
|
91
|
-
logger.error(f"❌ Invalid path: {
|
95
|
+
logger.error(f"❌ Invalid path: {resolved_path}")
|
92
96
|
return
|
93
97
|
|
94
98
|
if not macro_data:
|
@@ -182,24 +186,25 @@ def list(directory: str, debug: bool):
|
|
182
186
|
"""List available trajectory folders in a directory."""
|
183
187
|
logger = configure_logging(debug)
|
184
188
|
|
185
|
-
|
189
|
+
# Resolve directory (checks working dir, then project dir)
|
190
|
+
resolved_dir = PathResolver.resolve(directory, must_exist=True)
|
191
|
+
logger.info(f"📁 Scanning directory: {resolved_dir}")
|
186
192
|
|
187
193
|
try:
|
188
194
|
folders = []
|
189
|
-
for item in
|
190
|
-
|
191
|
-
|
192
|
-
macro_file
|
193
|
-
if os.path.exists(macro_file):
|
195
|
+
for item in resolved_dir.iterdir():
|
196
|
+
if item.is_dir():
|
197
|
+
macro_file = item / "macro.json"
|
198
|
+
if macro_file.exists():
|
194
199
|
# Load macro info
|
195
200
|
try:
|
196
|
-
macro_data = Trajectory.load_macro_sequence(
|
201
|
+
macro_data = Trajectory.load_macro_sequence(str(item))
|
197
202
|
description = macro_data.get("description", "No description")
|
198
203
|
total_actions = macro_data.get("total_actions", 0)
|
199
|
-
folders.append((item, description, total_actions))
|
204
|
+
folders.append((item.name, description, total_actions))
|
200
205
|
except Exception as e:
|
201
|
-
logger.debug(f"Error loading macro from {item}: {e}")
|
202
|
-
folders.append((item, "Error loading", 0))
|
206
|
+
logger.debug(f"Error loading macro from {item.name}: {e}")
|
207
|
+
folders.append((item.name, "Error loading", 0))
|
203
208
|
|
204
209
|
if not folders:
|
205
210
|
logger.info("📭 No trajectory folders found")
|
@@ -217,7 +222,7 @@ def list(directory: str, debug: bool):
|
|
217
222
|
|
218
223
|
# Still use console for table display as it's structured data
|
219
224
|
console.print(table)
|
220
|
-
logger.info(f"💡 Use 'droidrun macro replay {
|
225
|
+
logger.info(f"💡 Use 'droidrun macro replay {resolved_dir}/<folder>' to replay a trajectory")
|
221
226
|
|
222
227
|
except Exception as e:
|
223
228
|
logger.error(f"💥 Error: {e}")
|
droidrun/telemetry/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from .events import DroidAgentFinalizeEvent, DroidAgentInitEvent
|
2
|
-
from .tracker import capture, flush, print_telemetry_message
|
1
|
+
from droidrun.telemetry.events import DroidAgentFinalizeEvent, DroidAgentInitEvent
|
2
|
+
from droidrun.telemetry.tracker import capture, flush, print_telemetry_message
|
3
3
|
|
4
4
|
__all__ = ["capture", "flush", "DroidAgentInitEvent", "DroidAgentFinalizeEvent", "print_telemetry_message"]
|
droidrun/telemetry/events.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from typing import Dict
|
1
2
|
|
2
3
|
from pydantic import BaseModel
|
3
4
|
|
@@ -7,12 +8,11 @@ class TelemetryEvent(BaseModel):
|
|
7
8
|
|
8
9
|
class DroidAgentInitEvent(TelemetryEvent):
|
9
10
|
goal: str
|
10
|
-
|
11
|
+
llms: str | Dict[str, str]
|
11
12
|
tools: str
|
12
|
-
personas: str
|
13
13
|
max_steps: int
|
14
14
|
timeout: int
|
15
|
-
vision: bool
|
15
|
+
vision: bool | Dict[str, bool]
|
16
16
|
reasoning: bool
|
17
17
|
enable_tracing: bool
|
18
18
|
debug: bool
|
droidrun/telemetry/tracker.py
CHANGED
droidrun/tools/adb.py
CHANGED
@@ -66,7 +66,7 @@ class AdbTools(Tools):
|
|
66
66
|
self.screenshots: List[Dict[str, Any]] = []
|
67
67
|
# Trajectory saving level
|
68
68
|
self.save_trajectories = "none"
|
69
|
-
|
69
|
+
|
70
70
|
# LLM instances for specialized workflows
|
71
71
|
self.app_opener_llm = app_opener_llm
|
72
72
|
self.text_manipulator_llm = text_manipulator_llm
|
droidrun/tools/ios.py
CHANGED
@@ -39,13 +39,14 @@ SYSTEM_BUNDLE_IDENTIFIERS = [
|
|
39
39
|
class IOSTools(Tools):
|
40
40
|
"""Core UI interaction tools for iOS device control."""
|
41
41
|
|
42
|
-
def __init__(self, url: str, bundle_identifiers: List[str] =
|
42
|
+
def __init__(self, url: str, bundle_identifiers: List[str] | None = None) -> None:
|
43
43
|
"""Initialize the IOSTools instance.
|
44
44
|
|
45
45
|
Args:
|
46
46
|
url: iOS device URL. This is the URL of the iOS device. It is used to send requests to the iOS device.
|
47
47
|
bundle_identifiers: List of bundle identifiers to include in the list of packages
|
48
48
|
"""
|
49
|
+
|
49
50
|
self.clickable_elements_cache: List[Dict[str, Any]] = []
|
50
51
|
self.url = url
|
51
52
|
self.last_screenshot = None
|
@@ -57,7 +58,7 @@ class IOSTools(Tools):
|
|
57
58
|
self.last_tapped_rect: Optional[str] = (
|
58
59
|
None # Store last tapped element's rect for text input
|
59
60
|
)
|
60
|
-
self.bundle_identifiers = bundle_identifiers
|
61
|
+
self.bundle_identifiers = bundle_identifiers or []
|
61
62
|
logger.info(f"iOS device URL: {url}")
|
62
63
|
|
63
64
|
def get_state(self) -> List[Dict[str, Any]]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: droidrun
|
3
|
-
Version: 0.3.10.
|
3
|
+
Version: 0.3.10.dev5
|
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
|
@@ -13,8 +13,6 @@ Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Intended Audience :: Information Technology
|
14
14
|
Classifier: Intended Audience :: Science/Research
|
15
15
|
Classifier: License :: OSI Approved :: MIT License
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
18
16
|
Classifier: Programming Language :: Python :: 3.11
|
19
17
|
Classifier: Programming Language :: Python :: 3.12
|
20
18
|
Classifier: Programming Language :: Python :: 3.13
|
@@ -27,7 +25,7 @@ Classifier: Topic :: Software Development :: Testing
|
|
27
25
|
Classifier: Topic :: Software Development :: Testing :: Acceptance
|
28
26
|
Classifier: Topic :: System :: Emulators
|
29
27
|
Classifier: Topic :: Utilities
|
30
|
-
Requires-Python: >=3.
|
28
|
+
Requires-Python: >=3.11
|
31
29
|
Requires-Dist: adbutils>=2.10.2
|
32
30
|
Requires-Dist: apkutils==2.0.0
|
33
31
|
Requires-Dist: arize-phoenix>=12.3.0
|
@@ -38,6 +36,14 @@ Requires-Dist: rich>=14.1.0
|
|
38
36
|
Provides-Extra: anthropic
|
39
37
|
Requires-Dist: anthropic>=0.67.0; extra == 'anthropic'
|
40
38
|
Requires-Dist: llama-index-llms-anthropic<0.9.0,>=0.8.6; extra == 'anthropic'
|
39
|
+
Provides-Extra: backend
|
40
|
+
Requires-Dist: aiohttp>=3.9.0; extra == 'backend'
|
41
|
+
Requires-Dist: fastapi>=0.104.0; extra == 'backend'
|
42
|
+
Requires-Dist: pydantic-settings>=2.0.0; extra == 'backend'
|
43
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == 'backend'
|
44
|
+
Requires-Dist: python-multipart>=0.0.6; extra == 'backend'
|
45
|
+
Requires-Dist: uvicorn[standard]>=0.24.0; extra == 'backend'
|
46
|
+
Requires-Dist: websockets>=12.0; extra == 'backend'
|
41
47
|
Provides-Extra: deepseek
|
42
48
|
Requires-Dist: llama-index-llms-deepseek>=0.2.1; extra == 'deepseek'
|
43
49
|
Provides-Extra: dev
|
@@ -0,0 +1,61 @@
|
|
1
|
+
droidrun/__init__.py,sha256=c2exmv8MuTJ6wWXqzPR30pKGENeIgWe5ytY5hSQYuBc,621
|
2
|
+
droidrun/__main__.py,sha256=8HpscyKn49EH05wXIdoxMiU43xPKb1czq8Aze2vIIqI,106
|
3
|
+
droidrun/portal.py,sha256=Z4daRlMOpsiGxtJ4csuEaEiXAfGM5otbbrcrHvGhAB4,6161
|
4
|
+
droidrun/agent/__init__.py,sha256=91sM0qTmdV5trlXOWE4D_nRhXVPgHKMnYU_9Stc_obQ,209
|
5
|
+
droidrun/agent/usage.py,sha256=6PVeHctNa0EmHmNPTdOUv5e3-EK6AMu6D2Pz5OMqs5c,7145
|
6
|
+
droidrun/agent/codeact/__init__.py,sha256=lagBdrury33kbHN1XEZ-xzJ-RywmpkUUoUidOno9ym8,96
|
7
|
+
droidrun/agent/codeact/codeact_agent.py,sha256=r7sjVhsmgMdXdrCwCDxLFJE9Eeh9_E1Jd39Fs7T7iX8,20810
|
8
|
+
droidrun/agent/codeact/events.py,sha256=kRKTQPzogPiQwmOCc_fGcg1g1zDXXVeBpDl45GTdpYU,734
|
9
|
+
droidrun/agent/common/constants.py,sha256=q7ywmOXCsJZg8m9ctpzQ-nxvuj5GMn28Pr8z3dMj1Rg,94
|
10
|
+
droidrun/agent/common/events.py,sha256=rbPWdlqNNMdnVjYhJOL2mJcNNORHhjXOkY8XiLPzp7c,1182
|
11
|
+
droidrun/agent/context/__init__.py,sha256=-CiAv66qym_WgFy5vCRfNLxmiprmEbssu6S_2jj0LZw,452
|
12
|
+
droidrun/agent/context/episodic_memory.py,sha256=0WKmOPe_KDWGdxudUXkmNVO1vj7L1g2zpyhAA54E1Lk,308
|
13
|
+
droidrun/agent/context/task_manager.py,sha256=GXrGuBr8cukoLBRmvGIRsq0otwCC4s7N0NAVYql9oGY,5023
|
14
|
+
droidrun/agent/droid/__init__.py,sha256=3Kzejs0p2hqKzgMc253W147P-Y84bYnQX7AZ4pybIsU,297
|
15
|
+
droidrun/agent/droid/droid_agent.py,sha256=urCFKVyNz1jF_CFc7PTVEG3m_tFpwlmDOhwNZCa0lgk,21761
|
16
|
+
droidrun/agent/droid/events.py,sha256=eAxrGzA1yUGutInecFML0ms_361NgYmunK8XJ5-AEjE,3876
|
17
|
+
droidrun/agent/executor/__init__.py,sha256=2B531GoY7L1Hs_RJIVu62ARsP9mj86do8MiFl6ejpZ4,456
|
18
|
+
droidrun/agent/executor/events.py,sha256=sYMs24at_VtikPKqSh_yNRYByDt4JpS1jiEob9UjNrs,1377
|
19
|
+
droidrun/agent/executor/executor_agent.py,sha256=OQIVd7n0EjUZYwefbNRrhKheohLygQW9zDEpC4pDeq0,15153
|
20
|
+
droidrun/agent/executor/prompts.py,sha256=nUsr4oF1RjmByOVvBIgjw6_739hO3C916QEVYFjXuqw,7530
|
21
|
+
droidrun/agent/manager/__init__.py,sha256=mXvIvRihVAlLXOVQgvA9wsMdcZ2ICvhEg4ZoV97O32w,525
|
22
|
+
droidrun/agent/manager/events.py,sha256=X0tUwCX2mU8I4bGR4JW2NmUqiOrX-Hrb017vGVPVyHw,855
|
23
|
+
droidrun/agent/manager/manager_agent.py,sha256=fCDIFnpHRq75iEEvGtnbB7DnEjtZ9ZTvdWRBjJzTEXU,21094
|
24
|
+
droidrun/agent/manager/prompts.py,sha256=qfDYcSbpWpnUaavAuPE6qY6Df6w25LmtY1mEiBUMti0,2060
|
25
|
+
droidrun/agent/oneflows/app_starter_workflow.py,sha256=MSJ6_jfbiCfSIjnw-qfSDFDuqsUS6rUGLsdKVj43wvY,3525
|
26
|
+
droidrun/agent/oneflows/text_manipulator.py,sha256=mO59DF1uif9poUWy90UehrBmHbNxL9ph4Evtgt1ODbQ,8751
|
27
|
+
droidrun/agent/utils/__init__.py,sha256=Oro0oyiz1xzRpchWLDA1TZJELJNSwBOb2WdGgknthKo,244
|
28
|
+
droidrun/agent/utils/async_utils.py,sha256=_JhZ_ZfCkRTfPsufFDhUUds_Vp6z1-TokzUG4H8G7pc,338
|
29
|
+
droidrun/agent/utils/chat_utils.py,sha256=mginY1rbP5t06O3hz2RpJJJNzggaE8VhWjnFid844vw,13797
|
30
|
+
droidrun/agent/utils/device_state_formatter.py,sha256=3MuR3XQulnrsdzmMYfTEegA_XkYTTiETXMRtOtyqoC0,6889
|
31
|
+
droidrun/agent/utils/executer.py,sha256=vz6mLeV4xti3dd_bDBd4aWHDA6T-ym0EbdEicrtK0aA,4233
|
32
|
+
droidrun/agent/utils/inference.py,sha256=dupCtMYXUGuBJz9RqTgSsLYe_MOSB0LEhfHIdtFC8x0,3893
|
33
|
+
droidrun/agent/utils/llm_picker.py,sha256=m5PHBe8iex5n_a5fPwfPd5Qdup_atx4C6iv0-wTCGzY,7232
|
34
|
+
droidrun/agent/utils/message_utils.py,sha256=_wngf082gg232y_3pC_yn4fnPhHiyYAxhU4ewT78roo,2309
|
35
|
+
droidrun/agent/utils/tools.py,sha256=SW-nBSfKTgPxDafV8dVX345JwmW378y_x86sLxiISj4,9243
|
36
|
+
droidrun/agent/utils/trajectory.py,sha256=Z6C19Y9hsRxjLZWywqYWTApKU7PelvWM-5Tsl3h7KEw,19718
|
37
|
+
droidrun/cli/__init__.py,sha256=5cO-QBcUl5w35zO18OENj4OShdglQjn8Ne9aqgSh-PM,167
|
38
|
+
droidrun/cli/logs.py,sha256=lZX44S7pvrpbwfIXX6WYVPeDdvjjRozRb-oc6u-yCks,12686
|
39
|
+
droidrun/cli/main.py,sha256=dJdKleue-kLZs8xfQ3s2m_XiWm3ShrFy46Ne0S5P0JU,26171
|
40
|
+
droidrun/config_manager/__init__.py,sha256=-3FZJ2K985yhrIq2uPtlutCImdVzWvckdL1X4XCFi5s,547
|
41
|
+
droidrun/config_manager/app_card_loader.py,sha256=WKU3knxOcUo4v2mNh0XPljUW03Sc1fK4yBJVDERAeJY,5055
|
42
|
+
droidrun/config_manager/config_manager.py,sha256=4XUBTJnkoO_9AFU13j5nNygFIQFHyZ_Q_b3R6b796m4,21529
|
43
|
+
droidrun/config_manager/path_resolver.py,sha256=R9Yf3JWdrdvNXSg-6yXBO2NSr8HTuSvJfGcuyz0dY-I,3417
|
44
|
+
droidrun/config_manager/prompt_loader.py,sha256=nzlL3YMyteY91fOMryQD3XRny_2oytAmaXRZfLBNH2M,2450
|
45
|
+
droidrun/macro/__init__.py,sha256=TKRNlMJqClV1p1dkfES4eo-Bq1VkSiTC1DDMxMjnUWE,357
|
46
|
+
droidrun/macro/__main__.py,sha256=MWdBvQVhOoeKlC8atDwjVbPSn0-XNt4PDbpCCoeJuUk,193
|
47
|
+
droidrun/macro/cli.py,sha256=hlnQVY399El26cpFiXiP3-lcXB_gh6SDpAoPbCiMqsA,9161
|
48
|
+
droidrun/macro/replay.py,sha256=ILhnvN3VYhMK13wkaD5oDwP4wCYTniwcgesUON-9L5o,10721
|
49
|
+
droidrun/telemetry/__init__.py,sha256=2G9PwAuVWsd6qRMKSscssvmL57ILlOK5EV0KezPiF1I,271
|
50
|
+
droidrun/telemetry/events.py,sha256=y-i2d5KiPkikVXrzMQu87osy1LAZTBIx8DlPIWGAXG0,486
|
51
|
+
droidrun/telemetry/phoenix.py,sha256=JHdFdRHXu7cleAb4X4_Y5yn5zPSIApwyKCOxoaj_gf4,7117
|
52
|
+
droidrun/telemetry/tracker.py,sha256=YWOkyLE8XiHainVSB77JE37y-rloOYVYs6j53Aw1J8A,2735
|
53
|
+
droidrun/tools/__init__.py,sha256=BbQFKuPn-5MwGzr-3urMDK8S1ZsP96D96y7WTJYB3AA,271
|
54
|
+
droidrun/tools/adb.py,sha256=X9fvrQWBTCKkWTB4oXfRj5PRb__SA8zO0J0-TMbsJ1U,43908
|
55
|
+
droidrun/tools/ios.py,sha256=GMYbiNNBeHLwVQAo4_fEZ7snr4JCHE6sG11rcuPvSpk,21831
|
56
|
+
droidrun/tools/tools.py,sha256=0eAZFTaY10eiiUcJM4AkURmTGX-O1RRXjpQ5MHj2Ydo,5241
|
57
|
+
droidrun-0.3.10.dev5.dist-info/METADATA,sha256=VAVgYvK3zhdx2jLhH8DdvYrU4Oba3d2453aUOt4MQKc,7429
|
58
|
+
droidrun-0.3.10.dev5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
59
|
+
droidrun-0.3.10.dev5.dist-info/entry_points.txt,sha256=o259U66js8TIybQ7zs814Oe_LQ_GpZsp6a9Cr-xm5zE,51
|
60
|
+
droidrun-0.3.10.dev5.dist-info/licenses/LICENSE,sha256=s-uxn9qChu-kFdRXUp6v_0HhsaJ_5OANmfNOFVm2zdk,1069
|
61
|
+
droidrun-0.3.10.dev5.dist-info/RECORD,,
|
@@ -1,26 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Prompt templates for the CodeActAgent.
|
3
|
-
|
4
|
-
This module contains all the prompts used by the CodeActAgent,
|
5
|
-
separated from the workflow logic for better maintainability.
|
6
|
-
"""
|
7
|
-
|
8
|
-
|
9
|
-
# User prompt template that presents the current request and prompts for reasoning
|
10
|
-
DEFAULT_CODE_ACT_USER_PROMPT = """**Current Request:**
|
11
|
-
{goal}
|
12
|
-
|
13
|
-
**Is the precondition met? What is your reasoning and the next step to address this request?** Explain your thought process then provide code in ```python ... ``` tags if needed."""""
|
14
|
-
|
15
|
-
# Prompt to remind the agent to provide thoughts before code
|
16
|
-
DEFAULT_NO_THOUGHTS_PROMPT = """Your previous response provided code without explaining your reasoning first. Remember to always describe your thought process and plan *before* providing the code block.
|
17
|
-
|
18
|
-
The code you provided will be executed below.
|
19
|
-
|
20
|
-
Now, describe the next step you will take to address the original goal: {goal}"""
|
21
|
-
|
22
|
-
# Export all prompts
|
23
|
-
__all__ = [
|
24
|
-
"DEFAULT_CODE_ACT_USER_PROMPT",
|
25
|
-
"DEFAULT_NO_THOUGHTS_PROMPT"
|
26
|
-
]
|
@@ -1,16 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
from typing import List
|
3
|
-
|
4
|
-
|
5
|
-
@dataclass
|
6
|
-
class AgentPersona:
|
7
|
-
"""Represents a specialized agent persona with its configuration."""
|
8
|
-
name: str
|
9
|
-
system_prompt: str
|
10
|
-
user_prompt: str
|
11
|
-
description: str
|
12
|
-
allowed_tools: List[str]
|
13
|
-
required_context: List[str]
|
14
|
-
expertise_areas: List[str]
|
15
|
-
|
16
|
-
AppAgent = AgentPersona
|
@@ -1,66 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Context Injection Manager - Manages specialized agent personas with dynamic tool and context injection.
|
3
|
-
|
4
|
-
This module provides the ContextInjectionManager class that manages different agent personas,
|
5
|
-
each with specific system prompts, contexts, and tool subsets tailored for specialized tasks.
|
6
|
-
"""
|
7
|
-
|
8
|
-
#import chromadb
|
9
|
-
import json
|
10
|
-
import logging
|
11
|
-
from typing import List, Optional
|
12
|
-
|
13
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
14
|
-
|
15
|
-
logger = logging.getLogger("droidrun")
|
16
|
-
|
17
|
-
class ContextInjectionManager:
|
18
|
-
"""
|
19
|
-
Manages different agent personas with specialized contexts and tool subsets.
|
20
|
-
|
21
|
-
This class is responsible for:
|
22
|
-
- Defining agent personas with specific capabilities
|
23
|
-
- Injecting appropriate system prompts based on agent type
|
24
|
-
- Filtering tool lists to match agent specialization
|
25
|
-
- Providing context-aware configurations for CodeActAgent instances
|
26
|
-
"""
|
27
|
-
|
28
|
-
def __init__(
|
29
|
-
self,
|
30
|
-
personas: List[AgentPersona]
|
31
|
-
):
|
32
|
-
"""Initialize the Context Injection Manager with predefined personas."""
|
33
|
-
|
34
|
-
self.personas = {}
|
35
|
-
for persona in personas:
|
36
|
-
self.personas[persona.name] = persona
|
37
|
-
|
38
|
-
|
39
|
-
def _load_persona(self, data: str) -> AgentPersona:
|
40
|
-
persona = json.loads(data)
|
41
|
-
logger.info(f"🎭 Loaded persona: {persona['name']}")
|
42
|
-
return AgentPersona(
|
43
|
-
name=persona['name'],
|
44
|
-
system_prompt=persona['system_prompt'],
|
45
|
-
allowed_tools=persona['allowed_tools'],
|
46
|
-
description=persona['description'],
|
47
|
-
expertise_areas=persona['expertise_areas'],
|
48
|
-
user_prompt=persona['user_prompt'],
|
49
|
-
required_context=persona['required_context'],
|
50
|
-
)
|
51
|
-
|
52
|
-
def get_persona(self, agent_type: str) -> Optional[AgentPersona]:
|
53
|
-
"""
|
54
|
-
Get a specific agent persona by type.
|
55
|
-
|
56
|
-
Args:
|
57
|
-
agent_type: The type of agent ("UIExpert" or "AppStarterExpert")
|
58
|
-
|
59
|
-
Returns:
|
60
|
-
AgentPersona instance or None if not found
|
61
|
-
"""
|
62
|
-
|
63
|
-
return self.personas.get(agent_type)
|
64
|
-
|
65
|
-
def get_all_personas(self) -> List[str]:
|
66
|
-
return self.personas
|
@@ -1,44 +0,0 @@
|
|
1
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
2
|
-
from droidrun.tools import Tools
|
3
|
-
|
4
|
-
APP_STARTER_EXPERT = AgentPersona(
|
5
|
-
name="AppStarterExpert",
|
6
|
-
description="Specialized in app launching",
|
7
|
-
expertise_areas=[
|
8
|
-
"app launching"
|
9
|
-
],
|
10
|
-
allowed_tools=[
|
11
|
-
Tools.start_app.__name__,
|
12
|
-
Tools.complete.__name__
|
13
|
-
],
|
14
|
-
required_context=[
|
15
|
-
"packages"
|
16
|
-
],
|
17
|
-
user_prompt="""
|
18
|
-
**Current Request:**
|
19
|
-
{goal}
|
20
|
-
**Is the precondition met? What is your reasoning and the next step to address this request?** Explain your thought process then provide code in ```python ... ``` tags if needed.""""",
|
21
|
-
|
22
|
-
system_prompt= """You are an App Starter Expert specialized in Android application lifecycle management. Your core expertise includes:
|
23
|
-
|
24
|
-
**Primary Capabilities:**
|
25
|
-
- Launch Android applications by package name
|
26
|
-
- Use proper package name format (com.example.app)
|
27
|
-
|
28
|
-
## Response Format:
|
29
|
-
Example of proper code format:
|
30
|
-
To launch the Calculator app, I need to use the start_app function with the correct package name.
|
31
|
-
```python
|
32
|
-
# Launch the Calculator app
|
33
|
-
start_app("com.android.calculator2")
|
34
|
-
complete(success=True)
|
35
|
-
```
|
36
|
-
|
37
|
-
In addition to the Python Standard Library and any functions you have already written, you can use the following functions:
|
38
|
-
{tool_descriptions}
|
39
|
-
|
40
|
-
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
41
|
-
|
42
|
-
You focus ONLY on app launching and package management - UI interactions within apps are handled by UI specialists.""",
|
43
|
-
|
44
|
-
)
|
@@ -1,96 +0,0 @@
|
|
1
|
-
from droidrun.agent.context.agent_persona import AgentPersona
|
2
|
-
from droidrun.tools import Tools
|
3
|
-
|
4
|
-
BIG_AGENT = AgentPersona(
|
5
|
-
name="Big Agent",
|
6
|
-
description="Big Agent. Use this as your Big Agent",
|
7
|
-
expertise_areas=[
|
8
|
-
"UI navigation", "button interactions", "text input",
|
9
|
-
"menu navigation", "form filling", "scrolling", "app launching"
|
10
|
-
],
|
11
|
-
allowed_tools=[
|
12
|
-
Tools.swipe.__name__,
|
13
|
-
Tools.input_text.__name__,
|
14
|
-
Tools.press_key.__name__,
|
15
|
-
Tools.drag.__name__,
|
16
|
-
Tools.tap_by_index.__name__,
|
17
|
-
Tools.start_app.__name__,
|
18
|
-
Tools.list_packages.__name__,
|
19
|
-
Tools.remember.__name__,
|
20
|
-
Tools.complete.__name__
|
21
|
-
],
|
22
|
-
required_context=[
|
23
|
-
"ui_state",
|
24
|
-
"screenshot",
|
25
|
-
],
|
26
|
-
user_prompt="""
|
27
|
-
**Current Request:**
|
28
|
-
{goal}
|
29
|
-
**Is the precondition met? What is your reasoning and the next step to address this request?**
|
30
|
-
Explain your thought process then provide code in ```python ... ``` tags if needed.
|
31
|
-
""""",
|
32
|
-
|
33
|
-
system_prompt="""
|
34
|
-
You are a helpful AI assistant that can write and execute Python code to solve problems.
|
35
|
-
|
36
|
-
You will be given a task to perform. You should output:
|
37
|
-
- Python code wrapped in ``` tags that provides the solution to the task, or a step towards the solution.
|
38
|
-
- If there is a precondition for the task, you MUST check if it is met.
|
39
|
-
- If a goal's precondition is unmet, fail the task by calling `complete(success=False, reason='...')` with an explanation.
|
40
|
-
- If you task is complete, you should use the complete(success:bool, reason:str) function within a code block to mark it as finished. The success parameter should be True if the task was completed successfully, and False otherwise. The reason parameter should be a string explaining the reason for failure if failed.
|
41
|
-
|
42
|
-
|
43
|
-
## Context:
|
44
|
-
The following context is given to you for analysis:
|
45
|
-
- **ui_state**: A list of all currently visible UI elements with their indices. Use this to understand what interactive elements are available on the screen.
|
46
|
-
- **screenshots**: A visual screenshot of the current state of the Android screen. This provides visual context for what the user sees. screenshots won't be saved in the chat history. So, make sure to describe what you see and explain the key parts of your plan in your thoughts, as those will be saved and used to assist you in future steps.
|
47
|
-
- **phone_state**: The current app you are navigating in. This tells you which application context you're working within.
|
48
|
-
- **chat history**: You are also given the history of your actions (if any) from your previous steps.
|
49
|
-
- **execution result**: The result of your last Action
|
50
|
-
NOTE: you don't have access to these inputs in your tool calling context
|
51
|
-
|
52
|
-
## Response Format:
|
53
|
-
Example of proper code format:
|
54
|
-
**Task Assignment:**
|
55
|
-
**Task:** "Precondition: Settings app is open. Goal: Navigate to Wi-Fi settings and connect to the network 'HomeNetwork'."
|
56
|
-
|
57
|
-
**(Step 1) Agent Analysis:** I can see the Settings app is open from the screenshot. This is a multi-step task that requires me to first navigate to Wi-Fi settings, then ensure Wi-Fi is enabled, and finally connect to 'HomeNetwork'. Let me start by finding and tapping on the Wi-Fi option in the settings menu. Looking at the UI elements, I can see "Wi-Fi" option at index 3.
|
58
|
-
|
59
|
-
**(Step 1) Agent Action:**
|
60
|
-
```python
|
61
|
-
# First step: Navigate to Wi-Fi settings
|
62
|
-
tap_by_index(3)
|
63
|
-
```
|
64
|
-
|
65
|
-
**(Step 2) Agent Analysis:** Good! I've successfully navigated to the Wi-Fi settings screen. Now I can see the Wi-Fi settings interface. I notice that Wi-Fi appears to be turned off based on the toggle switch at index 1. I need to turn it on before I can see available networks and connect to 'HomeNetwork'.
|
66
|
-
|
67
|
-
**(Step 2) Agent Action:**
|
68
|
-
```python
|
69
|
-
# Second step: Turn on Wi-Fi to see available networks
|
70
|
-
tap_by_index(1)
|
71
|
-
```
|
72
|
-
|
73
|
-
**(Step 3) Agent Analysis:** Excellent! Wi-Fi is now enabled and I can see a list of available networks appearing on the screen. I can see 'HomeNetwork' in the list at index 5. This is the final step - I need to tap on it to initiate the connection, which will complete my assigned task.
|
74
|
-
|
75
|
-
**(Step 3) Agent Action:**
|
76
|
-
```python
|
77
|
-
# Final step: Connect to the target network
|
78
|
-
tap_by_index(5)
|
79
|
-
complete(success=True, reason="Successfully navigated to Wi-Fi settings and initiated connection to HomeNetwork")
|
80
|
-
```
|
81
|
-
```
|
82
|
-
|
83
|
-
## Tools:
|
84
|
-
In addition to the Python Standard Library and any functions you have already written, you can use the following functions:
|
85
|
-
{tool_descriptions}
|
86
|
-
|
87
|
-
|
88
|
-
## Final Answer Guidelines:
|
89
|
-
- When providing a final answer, focus on directly answering the user's question in the response format given
|
90
|
-
- Present the results clearly and concisely as if you computed them directly
|
91
|
-
- Structure your response like you're directly answering the user's query, not explaining how you solved it
|
92
|
-
|
93
|
-
Reminder: Always place your Python code between ```...``` tags when you want to run code.
|
94
|
-
"""
|
95
|
-
|
96
|
-
)
|