droidrun 0.3.5__py3-none-any.whl → 0.3.6__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/cli/main.py CHANGED
@@ -285,7 +285,7 @@ def cli(
285
285
  tracing: bool,
286
286
  debug: bool,
287
287
  use_tcp: bool,
288
- save_trajectory: str,
288
+ save_trajectory: str = "none",
289
289
  ):
290
290
  """DroidRun - Control your Android device through LLM agents."""
291
291
  pass
@@ -601,6 +601,7 @@ if __name__ == "__main__":
601
601
  base_url = None
602
602
  api_base = None
603
603
  ios = False
604
+ save_trajectory = "action"
604
605
  allow_drag = False
605
606
  run_command(
606
607
  command=command,
@@ -620,4 +621,5 @@ if __name__ == "__main__":
620
621
  api_key=api_key,
621
622
  allow_drag=allow_drag,
622
623
  ios=ios,
624
+ save_trajectory=save_trajectory,
623
625
  )
droidrun/portal.py CHANGED
@@ -85,16 +85,18 @@ def download_portal_apk(debug: bool = False):
85
85
  os.unlink(tmp.name)
86
86
 
87
87
 
88
- def enable_portal_accessibility(device: AdbDevice):
89
- device.shell(
90
- f"settings put secure enabled_accessibility_services {A11Y_SERVICE_NAME}"
91
- )
88
+ def enable_portal_accessibility(
89
+ device: AdbDevice, service_name: str = A11Y_SERVICE_NAME
90
+ ):
91
+ device.shell(f"settings put secure enabled_accessibility_services {service_name}")
92
92
  device.shell("settings put secure accessibility_enabled 1")
93
93
 
94
94
 
95
- def check_portal_accessibility(device: AdbDevice, debug: bool = False) -> bool:
95
+ def check_portal_accessibility(
96
+ device: AdbDevice, service_name: str = A11Y_SERVICE_NAME, debug: bool = False
97
+ ) -> bool:
96
98
  a11y_services = device.shell("settings get secure enabled_accessibility_services")
97
- if not A11Y_SERVICE_NAME in a11y_services:
99
+ if not service_name in a11y_services:
98
100
  if debug:
99
101
  print(a11y_services)
100
102
  return False
@@ -122,7 +124,7 @@ def ping_portal(device: AdbDevice, debug: bool = False):
122
124
  print(packages)
123
125
  raise Exception("Portal is not installed on the device")
124
126
 
125
- if not check_portal_accessibility(device, debug):
127
+ if not check_portal_accessibility(device, debug=debug):
126
128
  device.shell("am start -a android.settings.ACCESSIBILITY_SETTINGS")
127
129
  raise Exception(
128
130
  "Droidrun Portal is not enabled as an accessibility service on the device"
@@ -145,6 +147,17 @@ def ping_portal_tcp(device: AdbDevice, debug: bool = False):
145
147
  raise Exception(f"Failed to setup TCP forwarding: {e}")
146
148
 
147
149
 
150
+ def set_overlay_offset(device: AdbDevice, offset: int):
151
+ """
152
+ Set the overlay offset using the /overlay_offset portal content provider endpoint.
153
+ """
154
+ try:
155
+ cmd = f'content insert --uri "content://com.droidrun.portal/overlay_offset" --bind offset:i:{offset}'
156
+ device.shell(cmd)
157
+ except Exception as e:
158
+ raise Exception(f"Error setting overlay offset: {str(e)}")
159
+
160
+
148
161
  def test():
149
162
  device = adb.device()
150
163
  ping_portal(device, debug=False)
@@ -17,7 +17,7 @@ class DroidAgentInitEvent(TelemetryEvent):
17
17
  reflection: bool
18
18
  enable_tracing: bool
19
19
  debug: bool
20
- save_trajectories: str
20
+ save_trajectories: str = "none",
21
21
 
22
22
 
23
23
  class DroidAgentFinalizeEvent(TelemetryEvent):
droidrun/tools/adb.py CHANGED
@@ -61,10 +61,13 @@ class AdbTools(Tools):
61
61
  # Trajectory saving level
62
62
  self.save_trajectories = "none"
63
63
 
64
+ self.setup_keyboard()
65
+
64
66
  # Set up TCP forwarding if requested
65
67
  if self.use_tcp:
66
68
  self.setup_tcp_forward()
67
69
 
70
+
68
71
  def setup_tcp_forward(self) -> bool:
69
72
  """
70
73
  Set up ADB TCP port forwarding for communication with the portal app.
@@ -130,6 +133,24 @@ class AdbTools(Tools):
130
133
  logger.error(f"Failed to remove TCP port forwarding: {e}")
131
134
  return False
132
135
 
136
+ def setup_keyboard(self) -> bool:
137
+ """
138
+ Set up the DroidRun keyboard as the default input method.
139
+ Simple setup that just switches to DroidRun keyboard without saving/restoring.
140
+
141
+ Returns:
142
+ bool: True if setup was successful, False otherwise
143
+ """
144
+ try:
145
+ self.device.shell("ime enable com.droidrun.portal/.DroidrunKeyboardIME")
146
+ self.device.shell("ime set com.droidrun.portal/.DroidrunKeyboardIME")
147
+ logger.debug("DroidRun keyboard setup completed")
148
+ return True
149
+
150
+ except Exception as e:
151
+ logger.error(f"Failed to setup DroidRun keyboard: {e}")
152
+ return False
153
+
133
154
  def __del__(self):
134
155
  """Cleanup when the object is destroyed."""
135
156
  if hasattr(self, "tcp_forwarded") and self.tcp_forwarded:
@@ -444,61 +465,33 @@ class AdbTools(Tools):
444
465
  Result message
445
466
  """
446
467
  try:
447
- logger.debug(f"Inputting text: {text}")
448
-
449
- # if self.use_tcp and self.tcp_forwarded:
450
- # # Use TCP communication
451
- # encoded_text = base64.b64encode(text.encode()).decode()
452
-
453
- # payload = {"base64_text": encoded_text}
454
- # response = requests.post(
455
- # f"{self.tcp_base_url}/keyboard/input",
456
- # json=payload,
457
- # headers={"Content-Type": "application/json"},
458
- # timeout=10,
459
- # )
460
-
461
- # logger.debug(
462
- # f"Keyboard input TCP response: {response.status_code}, {response.text}"
463
- # )
464
-
465
- # if response.status_code != 200:
466
- # return f"Error: HTTP request failed with status {response.status_code}: {response.text}"
467
-
468
- # else:
469
- # Fallback to content provider method
470
- # Save the current keyboard
471
- original_ime = self.device.shell(
472
- "settings get secure default_input_method"
473
- )
474
- original_ime = original_ime.strip()
475
-
476
- # Enable the Droidrun keyboard
477
- self.device.shell("ime enable com.droidrun.portal/.DroidrunKeyboardIME")
478
468
 
479
- # Set the Droidrun keyboard as the default
480
- self.device.shell("ime set com.droidrun.portal/.DroidrunKeyboardIME")
481
-
482
- # Wait for keyboard to change
483
- time.sleep(1)
484
-
485
- # Encode the text to Base64
486
- encoded_text = base64.b64encode(text.encode()).decode()
469
+ if self.use_tcp and self.tcp_forwarded:
470
+ # Use TCP communication
471
+ encoded_text = base64.b64encode(text.encode()).decode()
472
+
473
+ payload = {"base64_text": encoded_text}
474
+ response = requests.post(
475
+ f"{self.tcp_base_url}/keyboard/input",
476
+ json=payload,
477
+ headers={"Content-Type": "application/json"},
478
+ timeout=10,
479
+ )
487
480
 
488
- cmd = f'content insert --uri "content://com.droidrun.portal/keyboard/input" --bind base64_text:s:"{encoded_text}"'
489
- self.device.shell(cmd)
481
+ logger.debug(
482
+ f"Keyboard input TCP response: {response.status_code}, {response.text}"
483
+ )
490
484
 
491
- # Wait for text input to complete
492
- time.sleep(0.5)
485
+ if response.status_code != 200:
486
+ return f"Error: HTTP request failed with status {response.status_code}: {response.text}"
493
487
 
494
- # Restore the original keyboard
495
- if original_ime and "com.droidrun.portal" not in original_ime:
496
- self.device.shell(f"ime set {original_ime}")
488
+ else:
489
+ # Fallback to content provider method
490
+ # Encode the text to Base64
491
+ encoded_text = base64.b64encode(text.encode()).decode()
497
492
 
498
- logger.debug(
499
- f"Text input completed: {text[:50]}{'...' if len(text) > 50 else ''}"
500
- )
501
- return f"Text input completed: {text[:50]}{'...' if len(text) > 50 else ''}"
493
+ cmd = f'content insert --uri "content://com.droidrun.portal/keyboard/input" --bind base64_text:s:"{encoded_text}"'
494
+ self.device.shell(cmd)
502
495
 
503
496
  if self._ctx:
504
497
  input_event = InputTextActionEvent(
@@ -528,13 +521,13 @@ class AdbTools(Tools):
528
521
  """
529
522
  try:
530
523
  logger.debug("Pressing key BACK")
531
- self.device.keyevent(3)
524
+ self.device.keyevent(4)
532
525
 
533
526
  if self._ctx:
534
527
  key_event = KeyPressActionEvent(
535
528
  action_type="key_press",
536
529
  description=f"Pressed key BACK",
537
- keycode=3,
530
+ keycode=4,
538
531
  key_name="BACK",
539
532
  )
540
533
  self._ctx.write_event_to_stream(key_event)
@@ -647,22 +640,50 @@ class AdbTools(Tools):
647
640
  except ValueError as e:
648
641
  return f"Error: {str(e)}"
649
642
 
650
- def take_screenshot(self) -> Tuple[str, bytes]:
643
+ def take_screenshot(self, hide_overlay: bool = True) -> Tuple[str, bytes]:
651
644
  """
652
645
  Take a screenshot of the device.
653
646
  This function captures the current screen and adds the screenshot to context in the next message.
654
647
  Also stores the screenshot in the screenshots list with timestamp for later GIF creation.
648
+
649
+ Args:
650
+ hide_overlay: Whether to hide the overlay elements during screenshot (default: True)
655
651
  """
656
652
  try:
657
653
  logger.debug("Taking screenshot")
658
-
659
- # Fallback to ADB screenshot method
660
- img = self.device.screenshot()
661
- img_buf = io.BytesIO()
662
654
  img_format = "PNG"
663
- img.save(img_buf, format=img_format)
664
- image_bytes = img_buf.getvalue()
665
- logger.debug("Screenshot taken via ADB")
655
+ image_bytes = None
656
+
657
+ if self.use_tcp and self.tcp_forwarded:
658
+ # Add hideOverlay parameter to URL
659
+ url = f"{self.tcp_base_url}/screenshot"
660
+ if not hide_overlay:
661
+ url += "?hideOverlay=false"
662
+
663
+ response = requests.get(url, timeout=10)
664
+ if response.status_code == 200:
665
+ tcp_response = response.json()
666
+
667
+ # Check if response has the expected format with data field
668
+ if tcp_response.get("status") == "success" and "data" in tcp_response:
669
+ # Decode base64 string to bytes
670
+ base64_data = tcp_response["data"]
671
+ image_bytes = base64.b64decode(base64_data)
672
+ logger.debug("Screenshot taken via TCP")
673
+ else:
674
+ # Handle error response from server
675
+ error_msg = tcp_response.get("error", "Unknown error")
676
+ raise ValueError(f"Error taking screenshot via TCP: {error_msg}")
677
+ else:
678
+ raise ValueError(f"Error taking screenshot via TCP: {response.status_code}")
679
+
680
+ else:
681
+ # Fallback to ADB screenshot method
682
+ img = self.device.screenshot()
683
+ img_buf = io.BytesIO()
684
+ img.save(img_buf, format=img_format)
685
+ image_bytes = img_buf.getvalue()
686
+ logger.debug("Screenshot taken via ADB")
666
687
 
667
688
  # Store screenshot with timestamp
668
689
  self.screenshots.append(
@@ -806,14 +827,25 @@ class AdbTools(Tools):
806
827
  "message": "Failed to parse state data from ContentProvider response",
807
828
  }
808
829
 
809
- if isinstance(state_data, dict) and "data" in state_data:
810
- data_str = state_data["data"]
811
- try:
812
- combined_data = json.loads(data_str)
813
- except json.JSONDecodeError:
830
+ if isinstance(state_data, dict):
831
+ data_str = None
832
+ if "data" in state_data:
833
+ data_str = state_data["data"]
834
+ elif "message" in state_data:
835
+ data_str = state_data["message"]
836
+
837
+ if data_str:
838
+ try:
839
+ combined_data = json.loads(data_str)
840
+ except json.JSONDecodeError:
841
+ return {
842
+ "error": "Parse Error",
843
+ "message": "Failed to parse JSON data from ContentProvider response",
844
+ }
845
+ else:
814
846
  return {
815
- "error": "Parse Error",
816
- "message": "Failed to parse JSON data from ContentProvider data field",
847
+ "error": "Format Error",
848
+ "message": "Neither 'data' nor 'message' field found in ContentProvider response",
817
849
  }
818
850
  else:
819
851
  return {
@@ -868,106 +900,6 @@ class AdbTools(Tools):
868
900
  "message": f"Error getting combined state: {str(e)}",
869
901
  }
870
902
 
871
- def get_a11y_tree(self) -> Dict[str, Any]:
872
- """
873
- Get just the accessibility tree using the /a11y_tree endpoint.
874
-
875
- Returns:
876
- Dictionary containing accessibility tree data
877
- """
878
- try:
879
- if self.use_tcp and self.tcp_forwarded:
880
- response = requests.get(f"{self.tcp_base_url}/a11y_tree", timeout=10)
881
-
882
- if response.status_code == 200:
883
- tcp_response = response.json()
884
-
885
- # Check if response has the expected format with data field
886
- if isinstance(tcp_response, dict) and "data" in tcp_response:
887
- data_str = tcp_response["data"]
888
- try:
889
- return json.loads(data_str)
890
- except json.JSONDecodeError:
891
- return {
892
- "error": "Parse Error",
893
- "message": "Failed to parse JSON data from TCP response data field",
894
- }
895
- else:
896
- # Fallback: assume direct JSON format
897
- return tcp_response
898
- else:
899
- return {
900
- "error": "HTTP Error",
901
- "message": f"HTTP request failed with status {response.status_code}",
902
- }
903
- else:
904
- # Fallback: use get_state and extract a11y_tree
905
- state = self.get_state()
906
- if "error" in state:
907
- return state
908
- return {"a11y_tree": state.get("a11y_tree", [])}
909
-
910
- except requests.exceptions.RequestException as e:
911
- return {
912
- "error": "TCP Error",
913
- "message": f"TCP request failed: {str(e)}",
914
- }
915
- except Exception as e:
916
- return {
917
- "error": str(e),
918
- "message": f"Error getting a11y tree: {str(e)}",
919
- }
920
-
921
- def get_phone_state(self) -> Dict[str, Any]:
922
- """
923
- Get just the phone state using the /phone_state endpoint.
924
-
925
- Returns:
926
- Dictionary containing phone state data
927
- """
928
- try:
929
- if self.use_tcp and self.tcp_forwarded:
930
- response = requests.get(f"{self.tcp_base_url}/phone_state", timeout=10)
931
-
932
- if response.status_code == 200:
933
- tcp_response = response.json()
934
-
935
- # Check if response has the expected format with data field
936
- if isinstance(tcp_response, dict) and "data" in tcp_response:
937
- data_str = tcp_response["data"]
938
- try:
939
- return json.loads(data_str)
940
- except json.JSONDecodeError:
941
- return {
942
- "error": "Parse Error",
943
- "message": "Failed to parse JSON data from TCP response data field",
944
- }
945
- else:
946
- # Fallback: assume direct JSON format
947
- return tcp_response
948
- else:
949
- return {
950
- "error": "HTTP Error",
951
- "message": f"HTTP request failed with status {response.status_code}",
952
- }
953
- else:
954
- # Fallback: use get_state and extract phone_state
955
- state = self.get_state()
956
- if "error" in state:
957
- return state
958
- return {"phone_state": state.get("phone_state", {})}
959
-
960
- except requests.exceptions.RequestException as e:
961
- return {
962
- "error": "TCP Error",
963
- "message": f"TCP request failed: {str(e)}",
964
- }
965
- except Exception as e:
966
- return {
967
- "error": str(e),
968
- "message": f"Error getting phone state: {str(e)}",
969
- }
970
-
971
903
  def ping(self) -> Dict[str, Any]:
972
904
  """
973
905
  Test the TCP connection using the /ping endpoint.
droidrun/tools/tools.py CHANGED
@@ -37,7 +37,6 @@ class Tools(ABC):
37
37
  step_screenshots.append(self.take_screenshot()[1])
38
38
  if step_ui_states is not None:
39
39
  step_ui_states.append(self.get_state())
40
-
41
40
  return result
42
41
  return wrapper
43
42
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: droidrun
3
- Version: 0.3.5
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==2.10.0
30
- Requires-Dist: aiofiles>=23.0.0
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: arize-phoenix
34
- Requires-Dist: click>=8.1.0
35
- Requires-Dist: llama-index
36
- Requires-Dist: llama-index-callbacks-arize-phoenix
37
- Requires-Dist: llama-index-llms-anthropic
38
- Requires-Dist: llama-index-llms-deepseek
39
- Requires-Dist: llama-index-llms-google-genai
40
- Requires-Dist: llama-index-llms-ollama
41
- Requires-Dist: llama-index-llms-openai
42
- Requires-Dist: llama-index-llms-openai-like
43
- Requires-Dist: openai>=1.0.0
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.7.0; extra == 'dev'
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.1.0; extra == 'dev'
54
- Requires-Dist: safety>=2.0.0; extra == 'dev'
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>
@@ -1,13 +1,14 @@
1
1
  droidrun/__init__.py,sha256=Cqt4NXZ-753220dlRZXglMkFT2ygcXSErMmqupGsi9A,622
2
2
  droidrun/__main__.py,sha256=78o1Wr_Z-NrZy9yLWmEfNfRRhAiJGBr4Xi3lmbgkx3w,105
3
- droidrun/portal.py,sha256=Bg3kVoNLJ2bTdk-4VuUr_i77yWJT2ZNLfT5WMumnZV8,4679
3
+ droidrun/portal.py,sha256=K9Yh2Lq6AC_7Qf5ySYuZr3CpYtN3hoD9cGy4D7I4zCc,5151
4
4
  droidrun/agent/__init__.py,sha256=4SqTJeGDvr_wT8rtN9J8hnN6P-pae663mkYr-JmzH4w,208
5
+ droidrun/agent/usage.py,sha256=ZTgqxRAgugJ9tk6ApZ2BJ5nB88pt9rhLyTFS5AnVUHo,7153
5
6
  droidrun/agent/codeact/__init__.py,sha256=ZLDGT_lTTzyNm7pcBzdyRIGHJ2ZgbInJdhXZRbJLhSQ,278
6
- droidrun/agent/codeact/codeact_agent.py,sha256=6Hltg6J4mdb5pOr5sFQVY-6SMWIcxWp6RZjct5nkiCc,16506
7
- droidrun/agent/codeact/events.py,sha256=skCfZ-5SR0YhhzZVxx8_VkUjfILk8rCv47k9pHNYhdc,634
7
+ droidrun/agent/codeact/codeact_agent.py,sha256=34lGKarbXcPRJVghRPlpJAt9ZDKBG2iwZmWYs-wz8DQ,17123
8
+ droidrun/agent/codeact/events.py,sha256=R3lNWSRTHQBkIBlel6CzyEUuozD40_9cugTvQ6PZsvw,720
8
9
  droidrun/agent/codeact/prompts.py,sha256=28HflWMNkC1ky0hGCzAxhJftjU2IIU1ZRUfya3S7M6I,1006
9
10
  droidrun/agent/common/default.py,sha256=P07el-PrHsoqQMYsYxSSln6mFl-QY75vzwp1Dll_XmY,259
10
- droidrun/agent/common/events.py,sha256=CUYdglSchK7W39VTbDdw24WJCwF4HfU0jKMbnjnFBdc,1085
11
+ droidrun/agent/common/events.py,sha256=xh1Qly2_ZC2edRr3Ad18QMe90ndRDxrJYZBWB3rqIjg,1183
11
12
  droidrun/agent/context/__init__.py,sha256=upSJilVQUwQYWJuGr_8QrmJaReV3SNAc_Z61wQZzbK4,697
12
13
  droidrun/agent/context/agent_persona.py,sha256=Mxd4HTyirWD-aqNlka1hQBdS-0I-lXJr2AjPMwDMUo8,390
13
14
  droidrun/agent/context/context_injection_manager.py,sha256=sA33q2KPtX_4Yap8wM11T6ewlZC_0FIbKPEc400SHrE,2188
@@ -20,35 +21,35 @@ droidrun/agent/context/personas/big_agent.py,sha256=Gl_y4ykz3apGc203-KG2UbSOwf7g
20
21
  droidrun/agent/context/personas/default.py,sha256=Xm07YCWoKjvlHAbQRtzE3vn7BVcz6wYcSVeg4FiojJQ,5060
21
22
  droidrun/agent/context/personas/ui_expert.py,sha256=j0OKfN1jQSrREHcVeomMTDPCWLsZVX4aeuWN4Y-x3z0,4739
22
23
  droidrun/agent/droid/__init__.py,sha256=3BfUVZiUQ8ATAJ_JmqQZQx53WoERRpQ4AyHW5WOgbRI,297
23
- droidrun/agent/droid/droid_agent.py,sha256=nKr8gV6aV_S5T4llhKokSBqL2uKF9ldxcnE29FOGTL8,16737
24
+ droidrun/agent/droid/droid_agent.py,sha256=Bd273hbefa7s1M-HW_FQEuhQWUKctDjhdlGyH6k455A,17650
24
25
  droidrun/agent/droid/events.py,sha256=hjYpWcSffqP83rNv_GyOEc3CNSrdvlVPdUkaRU6QDJc,722
25
26
  droidrun/agent/oneflows/reflector.py,sha256=I_tE0PBjvwWbS6SA8Qd41etxJglFgn8oScuKUxc9LEE,11621
26
27
  droidrun/agent/planner/__init__.py,sha256=Fu0Ewtd-dIRLgHIL1DB_9EEKvQS_f1vjB8jgO5TbJXg,364
27
- droidrun/agent/planner/events.py,sha256=oyt2FNrA2uVyUeVT65-N0AC6sWBFxSnwNEqWtnRYoFM,390
28
- droidrun/agent/planner/planner_agent.py,sha256=KELaoNOcoyB0He0B_A4iCi-hFyOTVO-s4-UclbQ7YjM,10910
28
+ droidrun/agent/planner/events.py,sha256=AJEC5lqMc5qLoj8V7lIN08KXT0YEg3i1anjLqiNS6is,475
29
+ droidrun/agent/planner/planner_agent.py,sha256=3Jx6NZJ3IFmb5zi2gKxmPZ2nuLjKyUOVec3SdNAuhVY,11456
29
30
  droidrun/agent/planner/prompts.py,sha256=Ci7Oeu3J4TAhx-tKGPZ9l6Wb3a81FSqC8cWW4jW73HI,6046
30
31
  droidrun/agent/utils/__init__.py,sha256=JK6ygRjw7gzcQSG0HBEYLoVGH54QQAxJJ7HpIS5mgyc,44
31
32
  droidrun/agent/utils/async_utils.py,sha256=IQBcWPwevm89B7R_UdMXk0unWeNCBA232b5kQGqoxNI,336
32
33
  droidrun/agent/utils/chat_utils.py,sha256=KzmiNasXb9d0qH12ylRsWooKV4_9LXy_QifaD_xf_O0,12726
33
- droidrun/agent/utils/executer.py,sha256=-iwdZpmpF0w116D7A_eDgeV0ZNXSuotVgBkM5lc0BNI,5202
34
- droidrun/agent/utils/llm_picker.py,sha256=16tNkNhEM9gD_uivzxLvuaa6s0Tz7Igu-3fxMP2lAtY,5968
35
- droidrun/agent/utils/trajectory.py,sha256=PU3nI3Zru580_bK0TvqUaf-5kiWvj6hFoedXkDgTqdc,17047
34
+ droidrun/agent/utils/executer.py,sha256=EBDGBMUAL80fJ6yyyt0v4XElhcjEGwi4_K4oU3_Loxo,5203
35
+ droidrun/agent/utils/llm_picker.py,sha256=V35nrOeSUeXoIV0eDKHBo3ESTAKj-N4NRX75i0LO1JM,7230
36
+ droidrun/agent/utils/trajectory.py,sha256=xvfj274AdRdIAVz72889ndoj-dD0_iOmLQBVQbXNcP4,19510
36
37
  droidrun/cli/__init__.py,sha256=DuwSRtZ8WILPd-nf-fZ7BaBsRgtofoInOF3JtJ9wag0,167
37
- droidrun/cli/logs.py,sha256=PsT_VbnOa_sOLXK4KkEJk4AsYCpscqrVoryMmLVwPG0,9714
38
- droidrun/cli/main.py,sha256=3RWvY19zY9ewzcasndxpul3BUPpMq4yhrtnuAIBkufM,18311
38
+ droidrun/cli/logs.py,sha256=-idRi3HTp7OfZRKAe9FPmiavPUYgQEdOqy3j5wXjOZI,9842
39
+ droidrun/cli/main.py,sha256=yW6TU7nk91zuM9QFHfoJz7wbTdJPNHnpoiXZfuA3gbo,18392
39
40
  droidrun/macro/__init__.py,sha256=333sMt19mA8sfQa4qPKbbCmr8Ej3nvpdxGXUZtVTEqM,344
40
41
  droidrun/macro/__main__.py,sha256=-zj42Bj7309oLPZbNsxZeNwIDaEe7Th1I4zF8yAHasw,193
41
42
  droidrun/macro/cli.py,sha256=GaL1wVWVE_AT0OxHgOJyW-q_kVu4PQ76KZKeYMQdoEk,9057
42
43
  droidrun/macro/replay.py,sha256=q_3ZcHVjvsdDfS2xyt_vuuwXGt9_1t38JD1cPsjzIfU,10764
43
44
  droidrun/telemetry/__init__.py,sha256=D4Mp02iGJH2Tjpv42Bzyo6_WC3NWj9Qy9hQPWFaCkhA,234
44
- droidrun/telemetry/events.py,sha256=FtPMMDAhxvOiCssJLCCr5FX93ulnPCbiFMhkPh8NLw4,517
45
+ droidrun/telemetry/events.py,sha256=OIYIs5stZtKz0g82W8WFE_h6q3jh0vUhc9_CwNTJ3a4,529
45
46
  droidrun/telemetry/tracker.py,sha256=Ljue6zivX8KnadXI9DivrayuWxAnUwbJKvCvNtY1Y4Y,2717
46
47
  droidrun/tools/__init__.py,sha256=9ReauavtSKDQG9ya9_Fr9O0TQnDFixgOPaP5n82_iEk,271
47
- droidrun/tools/adb.py,sha256=zFnVydQi42GZ1vh-4HT79dCQVBeCS6VObywyaIUUCmw,40832
48
+ droidrun/tools/adb.py,sha256=O4bl23QTIOG_ng1ukdWg87n01FVhNoSi3dBdgL6oaqs,38409
48
49
  droidrun/tools/ios.py,sha256=imzojiS6gqz4IKexUEz1ga7-flSOaC5QRpHIJTwcgSQ,21807
49
- droidrun/tools/tools.py,sha256=rqDe2gRyR45HVM15SwsW1aCTVZo5eleTxlh2hGqCHys,4785
50
- droidrun-0.3.5.dist-info/METADATA,sha256=k4-cv0Vud2ol8yqc1qkKWWxp2OrGxL12yeS-YUpc4K4,6685
51
- droidrun-0.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
- droidrun-0.3.5.dist-info/entry_points.txt,sha256=o259U66js8TIybQ7zs814Oe_LQ_GpZsp6a9Cr-xm5zE,51
53
- droidrun-0.3.5.dist-info/licenses/LICENSE,sha256=s-uxn9qChu-kFdRXUp6v_0HhsaJ_5OANmfNOFVm2zdk,1069
54
- droidrun-0.3.5.dist-info/RECORD,,
50
+ droidrun/tools/tools.py,sha256=Swlzo9A8B8YcgU6XNHRG1LNpo_-RljzhyVhnEYYm-G4,4772
51
+ droidrun-0.3.6.dist-info/METADATA,sha256=3iRkXCLUc8DjEDB0a89zXuhriSIZh5bytsVm8yWQDI8,6535
52
+ droidrun-0.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
+ droidrun-0.3.6.dist-info/entry_points.txt,sha256=o259U66js8TIybQ7zs814Oe_LQ_GpZsp6a9Cr-xm5zE,51
54
+ droidrun-0.3.6.dist-info/licenses/LICENSE,sha256=s-uxn9qChu-kFdRXUp6v_0HhsaJ_5OANmfNOFVm2zdk,1069
55
+ droidrun-0.3.6.dist-info/RECORD,,