droidrun 0.5.0.dev3__tar.gz → 0.5.0.dev5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/PKG-INFO +1 -1
  2. droidrun-0.5.0.dev5/docs/ favicon.svg +5 -0
  3. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/custom.css +0 -6
  4. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/docs.json +6 -3
  5. droidrun-0.5.0.dev5/docs/favicon-dark.png +0 -0
  6. droidrun-0.5.0.dev5/docs/favicon.png +0 -0
  7. droidrun-0.5.0.dev5/docs/logo/dark.png +0 -0
  8. droidrun-0.5.0.dev5/docs/logo/light.png +0 -0
  9. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/codeact/codeact_agent.py +11 -6
  10. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/codeact/tools_agent.py +6 -1
  11. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/droid/droid_agent.py +38 -22
  12. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/droid/state.py +1 -0
  13. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/manager/manager_agent.py +9 -8
  14. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/manager/stateless_manager_agent.py +6 -5
  15. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/__init__.py +2 -1
  16. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/base.py +6 -0
  17. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/cloud.py +61 -58
  18. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ui/provider.py +7 -3
  19. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/pyproject.toml +1 -1
  20. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/uv.lock +1 -1
  21. droidrun-0.5.0.dev3/docs/favicon.png +0 -0
  22. droidrun-0.5.0.dev3/docs/logo/dark.svg +0 -10
  23. droidrun-0.5.0.dev3/docs/logo/light.svg +0 -10
  24. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.dockerignore +0 -0
  25. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/black.yml +0 -0
  26. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/bounty.yml +0 -0
  27. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/claude-code-review.yml +0 -0
  28. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/claude.yml +0 -0
  29. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/docker.yml +0 -0
  30. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.github/workflows/publish.yml +0 -0
  31. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.gitignore +0 -0
  32. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/.python-version +0 -0
  33. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/CHANGELOG.md +0 -0
  34. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/CONTRIBUTING.md +0 -0
  35. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/Dockerfile +0 -0
  36. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/LICENSE +0 -0
  37. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/MANIFEST.in +0 -0
  38. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/README.md +0 -0
  39. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/SKILL.md +0 -0
  40. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/concepts/agent.mdx +0 -0
  41. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/concepts/android-tools.mdx +0 -0
  42. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/concepts/models.mdx +0 -0
  43. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/concepts/portal-app.mdx +0 -0
  44. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/cli.mdx +0 -0
  45. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/gemini.mdx +0 -0
  46. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/ollama.mdx +0 -0
  47. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/openailike.mdx +0 -0
  48. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/overview.mdx +0 -0
  49. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/guides/telemetry.mdx +0 -0
  50. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/images/portal_apk.png +0 -0
  51. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/overview.mdx +0 -0
  52. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v3/quickstart.mdx +0 -0
  53. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/concepts/architecture.mdx +0 -0
  54. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/concepts/events-and-workflows.mdx +0 -0
  55. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/concepts/prompts.mdx +0 -0
  56. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/concepts/scripter-agent.mdx +0 -0
  57. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/concepts/shared-state.mdx +0 -0
  58. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/app-cards.mdx +0 -0
  59. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/credentials.mdx +0 -0
  60. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/custom-tools.mdx +0 -0
  61. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/custom-variables.mdx +0 -0
  62. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/structured-output.mdx +0 -0
  63. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/telemetry.mdx +0 -0
  64. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/features/tracing.mdx +0 -0
  65. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/guides/cli.mdx +0 -0
  66. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/guides/device-setup.mdx +0 -0
  67. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/guides/docker.mdx +0 -0
  68. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/guides/migration-v3-to-v4.mdx +0 -0
  69. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/guides/overview.mdx +0 -0
  70. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/overview.mdx +0 -0
  71. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/quickstart.mdx +0 -0
  72. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/adb-tools.mdx +0 -0
  73. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/base-tools.mdx +0 -0
  74. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/configuration.mdx +0 -0
  75. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/droid-agent.mdx +0 -0
  76. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/ios-tools.mdx +0 -0
  77. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v4/sdk/reference.mdx +0 -0
  78. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/concepts/architecture.mdx +0 -0
  79. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/concepts/events-and-workflows.mdx +0 -0
  80. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/concepts/prompts.mdx +0 -0
  81. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/concepts/scripter-agent.mdx +0 -0
  82. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/concepts/shared-state.mdx +0 -0
  83. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/app-cards.mdx +0 -0
  84. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/credentials.mdx +0 -0
  85. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/custom-tools.mdx +0 -0
  86. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/custom-variables.mdx +0 -0
  87. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/structured-output.mdx +0 -0
  88. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/telemetry.mdx +0 -0
  89. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/features/tracing.mdx +0 -0
  90. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/guides/cli.mdx +0 -0
  91. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/guides/device-setup.mdx +0 -0
  92. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/guides/docker.mdx +0 -0
  93. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/guides/overview.mdx +0 -0
  94. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/overview.mdx +0 -0
  95. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/quickstart.mdx +0 -0
  96. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/adb-tools.mdx +0 -0
  97. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/base-tools.mdx +0 -0
  98. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/configuration.mdx +0 -0
  99. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/droid-agent.mdx +0 -0
  100. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/ios-tools.mdx +0 -0
  101. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/docs/v5/sdk/reference.mdx +0 -0
  102. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/__init__.py +0 -0
  103. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/__main__.py +0 -0
  104. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/__init__.py +0 -0
  105. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/action_context.py +0 -0
  106. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/action_result.py +0 -0
  107. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/codeact/__init__.py +0 -0
  108. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/codeact/events.py +0 -0
  109. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/codeact/xml_parser.py +0 -0
  110. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/common/__init__.py +0 -0
  111. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/common/constants.py +0 -0
  112. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/common/events.py +0 -0
  113. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/droid/__init__.py +0 -0
  114. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/droid/events.py +0 -0
  115. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/executor/__init__.py +0 -0
  116. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/executor/events.py +0 -0
  117. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/executor/executor_agent.py +0 -0
  118. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/executor/prompts.py +0 -0
  119. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/external/__init__.py +0 -0
  120. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/external/autoglm.py +0 -0
  121. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/external/mai_ui.py +0 -0
  122. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/manager/__init__.py +0 -0
  123. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/manager/events.py +0 -0
  124. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/manager/prompts.py +0 -0
  125. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/oneflows/__init__.py +0 -0
  126. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/oneflows/app_starter_workflow.py +0 -0
  127. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/oneflows/structured_output_agent.py +0 -0
  128. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/oneflows/text_manipulator.py +0 -0
  129. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/scripter/__init__.py +0 -0
  130. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/scripter/events.py +0 -0
  131. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/scripter/scripter_agent.py +0 -0
  132. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/tool_registry.py +0 -0
  133. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/trajectory/__init__.py +0 -0
  134. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/trajectory/writer.py +0 -0
  135. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/usage.py +0 -0
  136. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/__init__.py +0 -0
  137. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/actions.py +0 -0
  138. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/chat_utils.py +0 -0
  139. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/code_checker.py +0 -0
  140. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/executer.py +0 -0
  141. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/inference.py +0 -0
  142. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/llm_loader.py +0 -0
  143. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/llm_picker.py +0 -0
  144. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/prompt_resolver.py +0 -0
  145. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/signatures.py +0 -0
  146. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/tracing_setup.py +0 -0
  147. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/agent/utils/trajectory.py +0 -0
  148. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/__init__.py +0 -0
  149. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/app_card_provider.py +0 -0
  150. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/providers/__init__.py +0 -0
  151. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/providers/composite_provider.py +0 -0
  152. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/providers/local_provider.py +0 -0
  153. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/app_cards/providers/server_provider.py +0 -0
  154. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/__init__.py +0 -0
  155. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/doctor.py +0 -0
  156. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/event_handler.py +0 -0
  157. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/logs.py +0 -0
  158. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/main.py +0 -0
  159. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/__init__.py +0 -0
  160. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/app.py +0 -0
  161. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/commands.py +0 -0
  162. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/css/advanced_tab.tcss +0 -0
  163. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/css/app.tcss +0 -0
  164. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/css/models_tab.tcss +0 -0
  165. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/css/settings_screen.tcss +0 -0
  166. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/__init__.py +0 -0
  167. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/advanced_tab.py +0 -0
  168. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/agent_tab.py +0 -0
  169. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/data.py +0 -0
  170. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/models_tab.py +0 -0
  171. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/section.py +0 -0
  172. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/settings/settings_screen.py +0 -0
  173. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/__init__.py +0 -0
  174. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/command_dropdown.py +0 -0
  175. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/device_picker.py +0 -0
  176. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/input_bar.py +0 -0
  177. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/log_view.py +0 -0
  178. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/cli/tui/widgets/status_bar.py +0 -0
  179. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/app_cards/README.md +0 -0
  180. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/app_cards/app_cards.json +0 -0
  181. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/app_cards/gmail.md +0 -0
  182. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/credentials_example.yaml +0 -0
  183. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/codeact/system.jinja2 +0 -0
  184. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/codeact/tools_system.jinja2 +0 -0
  185. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/codeact/tools_user.jinja2 +0 -0
  186. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/codeact/user.jinja2 +0 -0
  187. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/executor/rev1.jinja2 +0 -0
  188. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/executor/system.jinja2 +0 -0
  189. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/manager/rev1.jinja2 +0 -0
  190. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/manager/stateless.jinja2 +0 -0
  191. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/manager/system.jinja2 +0 -0
  192. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/manager/trained.jinja2 +0 -0
  193. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config/prompts/scripter/system.jinja2 +0 -0
  194. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_example.yaml +0 -0
  195. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/__init__.py +0 -0
  196. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/config_manager.py +0 -0
  197. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/env_keys.py +0 -0
  198. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/loader.py +0 -0
  199. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/migrations/__init__.py +0 -0
  200. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/migrations/v002_add_code_exec.py +0 -0
  201. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/path_resolver.py +0 -0
  202. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/prompt_loader.py +0 -0
  203. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/config_manager/safe_execution.py +0 -0
  204. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/credential_manager/__init__.py +0 -0
  205. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/credential_manager/credential_manager.py +0 -0
  206. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/credential_manager/file_credential_manager.py +0 -0
  207. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/log_handlers.py +0 -0
  208. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/macro/__init__.py +0 -0
  209. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/macro/__main__.py +0 -0
  210. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/macro/cli.py +0 -0
  211. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/macro/replay.py +0 -0
  212. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/mcp/__init__.py +0 -0
  213. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/mcp/adapter.py +0 -0
  214. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/mcp/client.py +0 -0
  215. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/mcp/config.py +0 -0
  216. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/portal.py +0 -0
  217. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/telemetry/__init__.py +0 -0
  218. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/telemetry/events.py +0 -0
  219. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/telemetry/langfuse_processor.py +0 -0
  220. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/telemetry/phoenix.py +0 -0
  221. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/telemetry/tracker.py +0 -0
  222. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/__init__.py +0 -0
  223. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/android/__init__.py +0 -0
  224. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/android/portal_client.py +0 -0
  225. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/android.py +0 -0
  226. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/ios.py +0 -0
  227. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/recording.py +0 -0
  228. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/driver/stealth.py +0 -0
  229. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/filters/__init__.py +0 -0
  230. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/filters/base.py +0 -0
  231. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/filters/concise_filter.py +0 -0
  232. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/filters/detailed_filter.py +0 -0
  233. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/formatters/__init__.py +0 -0
  234. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/formatters/base.py +0 -0
  235. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/formatters/indexed_formatter.py +0 -0
  236. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/helpers/__init__.py +0 -0
  237. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/helpers/coordinate.py +0 -0
  238. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/helpers/element_search.py +0 -0
  239. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/helpers/geometry.py +0 -0
  240. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ios/__init__.py +0 -0
  241. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ui/__init__.py +0 -0
  242. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ui/ios_provider.py +0 -0
  243. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ui/state.py +0 -0
  244. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/droidrun/tools/ui/stealth_state.py +0 -0
  245. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/gen-docs-sdk-ref.sh +0 -0
  246. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/setup.py +0 -0
  247. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/static/droidrun-dark.png +0 -0
  248. {droidrun-0.5.0.dev3 → droidrun-0.5.0.dev5}/static/droidrun.png +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: droidrun
3
- Version: 0.5.0.dev3
3
+ Version: 0.5.0.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
@@ -0,0 +1,5 @@
1
+ <svg width="447" height="447" viewBox="0 0 447 447" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="447" height="447" fill="black"/>
3
+ <path d="M237.275 280.157H169.707L169.72 231.845H237.275V280.157L280.79 235.371C282.498 233.612 283.454 231.257 283.454 228.806V181.088V93.7789C283.454 89.3915 277.983 87.3868 275.148 90.7352L237.275 135.469V181.088H213.44L128.108 280.157V322.5C128.108 325.969 130.92 328.781 134.388 328.781H189.794C192.483 328.781 195.045 327.631 196.833 325.621L237.275 280.157Z" fill="white"/>
4
+ <path d="M237.275 328.781H283.454V280.157H237.275V328.781Z" fill="white"/>
5
+ </svg>
@@ -6,12 +6,6 @@ a[href="https://mobilerun.ai"] {
6
6
  max-height: none !important;
7
7
  }
8
8
 
9
- img[src*="/logo/light.svg"],
10
- img[src*="/logo/dark.svg"] {
11
- height: 3rem !important;
12
- max-height: none !important;
13
- width: auto !important;
14
- }
15
9
 
16
10
  /* Override Mintlify's max-w-xl on content-area */
17
11
  #content-area {
@@ -7,7 +7,10 @@
7
7
  "light": "#07C983",
8
8
  "dark": "#0D9373"
9
9
  },
10
- "favicon": "/favicon.png",
10
+ "favicon": {
11
+ "light": "/favicon.png",
12
+ "dark": "/favicon-dark.png"
13
+ },
11
14
  "icons": {
12
15
  "library": "lucide"
13
16
  },
@@ -214,8 +217,8 @@
214
217
  ]
215
218
  },
216
219
  "logo": {
217
- "light": "/logo/light.svg",
218
- "dark": "/logo/dark.svg",
220
+ "light": "/logo/light.png",
221
+ "dark": "/logo/dark.png",
219
222
  "href": "https://droidrun.ai"
220
223
  },
221
224
  "navbar": {
Binary file
Binary file
Binary file
@@ -3,25 +3,25 @@ import inspect
3
3
  import logging
4
4
  from typing import TYPE_CHECKING, Optional, Type
5
5
 
6
- from pydantic import BaseModel
7
6
  from llama_index.core.llms.llm import LLM
8
7
  from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
9
8
  from opentelemetry import trace
9
+ from pydantic import BaseModel
10
10
 
11
11
  from droidrun.agent.codeact.events import (
12
- CodeActInputEvent,
13
- CodeActResponseEvent,
14
12
  CodeActCodeEvent,
15
- CodeActOutputEvent,
16
13
  CodeActEndEvent,
14
+ CodeActInputEvent,
15
+ CodeActOutputEvent,
16
+ CodeActResponseEvent,
17
17
  )
18
18
  from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
19
19
  from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
20
20
  from droidrun.agent.usage import get_usage_from_response
21
21
  from droidrun.agent.utils.chat_utils import (
22
- to_chat_messages,
23
22
  extract_code_and_thought,
24
23
  limit_history,
24
+ to_chat_messages,
25
25
  )
26
26
  from droidrun.agent.utils.executer import ExecuterState, SimpleCodeExecutor
27
27
  from droidrun.agent.utils.inference import acall_with_retries
@@ -30,6 +30,7 @@ from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
30
30
  from droidrun.config_manager.config_manager import AgentConfig, TracingConfig
31
31
  from droidrun.config_manager.path_resolver import PathResolver
32
32
  from droidrun.config_manager.prompt_loader import PromptLoader
33
+ from droidrun.tools.driver.base import DeviceDisconnectedError
33
34
 
34
35
  # Legacy codeact prompt paths (used when code_exec=true but config points to tools defaults)
35
36
  _LEGACY_SYSTEM_PROMPT = "config/prompts/codeact/system.jinja2"
@@ -285,6 +286,8 @@ class CodeActAgent(Workflow):
285
286
  )
286
287
  await ctx.store.set("screenshot", screenshot)
287
288
  logger.debug("📸 Screenshot captured for CodeAct")
289
+ except DeviceDisconnectedError:
290
+ raise
288
291
  except Exception as e:
289
292
  logger.warning(f"Failed to capture screenshot: {e}")
290
293
 
@@ -313,6 +316,8 @@ class CodeActAgent(Workflow):
313
316
  {"text": f"\n{ui_state.formatted_text}\n"}
314
317
  )
315
318
 
319
+ except DeviceDisconnectedError:
320
+ raise
316
321
  except Exception as e:
317
322
  logger.warning(f"⚠️ Error retrieving state from the connected device: {e}")
318
323
  if self.debug:
@@ -383,7 +388,7 @@ class CodeActAgent(Workflow):
383
388
  "Your previous response provided code without explaining your reasoning first. "
384
389
  "Remember to always describe your thought process and plan *before* providing the code block.\n\n"
385
390
  "The code you provided will be executed below.\n\n"
386
- f"Now, describe the next step you will take to address the original goal."
391
+ "Now, describe the next step you will take to address the original goal."
387
392
  )
388
393
  self.shared_state.message_history.append(
389
394
  {"role": "user", "content": [{"text": no_thoughts_text}]}
@@ -17,6 +17,7 @@ from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow,
17
17
  from opentelemetry import trace
18
18
  from pydantic import BaseModel
19
19
 
20
+ from droidrun.agent.action_result import ActionResult
20
21
  from droidrun.agent.codeact.events import (
21
22
  FastAgentEndEvent,
22
23
  FastAgentInputEvent,
@@ -31,7 +32,6 @@ from droidrun.agent.codeact.xml_parser import (
31
32
  format_tool_results,
32
33
  parse_tool_calls,
33
34
  )
34
- from droidrun.agent.action_result import ActionResult
35
35
  from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
36
36
  from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
37
37
  from droidrun.agent.usage import get_usage_from_response
@@ -41,6 +41,7 @@ from droidrun.agent.utils.prompt_resolver import PromptResolver
41
41
  from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
42
42
  from droidrun.config_manager.config_manager import AgentConfig, TracingConfig
43
43
  from droidrun.config_manager.prompt_loader import PromptLoader
44
+ from droidrun.tools.driver.base import DeviceDisconnectedError
44
45
 
45
46
  if TYPE_CHECKING:
46
47
  from droidrun.agent.action_context import ActionContext
@@ -235,6 +236,8 @@ class FastAgent(Workflow):
235
236
  )
236
237
  await ctx.store.set("screenshot", screenshot)
237
238
  logger.debug("📸 Screenshot captured for FastAgent")
239
+ except DeviceDisconnectedError:
240
+ raise
238
241
  except Exception as e:
239
242
  logger.warning(f"Failed to capture screenshot: {e}")
240
243
 
@@ -263,6 +266,8 @@ class FastAgent(Workflow):
263
266
  {"text": f"\n{ui_state.formatted_text}\n"}
264
267
  )
265
268
 
269
+ except DeviceDisconnectedError:
270
+ raise
266
271
  except Exception as e:
267
272
  logger.warning(f"⚠️ Error retrieving state from the connected device: {e}")
268
273
  if self.debug:
@@ -9,14 +9,16 @@ Architecture:
9
9
 
10
10
  import logging
11
11
  import traceback
12
- from typing import TYPE_CHECKING, Type, Awaitable, Union
12
+ from typing import TYPE_CHECKING, Awaitable, Type, Union
13
13
 
14
- from pydantic import BaseModel
14
+ from async_adbutils import adb
15
15
  from llama_index.core.llms.llm import LLM
16
16
  from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
17
-
17
+ from opentelemetry import trace
18
+ from pydantic import BaseModel
18
19
  from workflows.events import Event
19
20
  from workflows.handler import WorkflowHandler
21
+
20
22
  from droidrun.agent.action_context import ActionContext
21
23
  from droidrun.agent.codeact import CodeActAgent, FastAgent
22
24
  from droidrun.agent.codeact.events import CodeActOutputEvent, FastAgentOutputEvent
@@ -37,12 +39,14 @@ from droidrun.agent.droid.events import (
37
39
  )
38
40
  from droidrun.agent.droid.state import DroidAgentState
39
41
  from droidrun.agent.executor import ExecutorAgent
42
+ from droidrun.agent.external import load_agent
40
43
  from droidrun.agent.manager import ManagerAgent, StatelessManagerAgent
44
+ from droidrun.agent.oneflows.structured_output_agent import StructuredOutputAgent
41
45
  from droidrun.agent.oneflows.text_manipulator import run_text_manipulation_agent
42
46
  from droidrun.agent.scripter import ScripterAgent
43
- from droidrun.agent.oneflows.structured_output_agent import StructuredOutputAgent
44
47
  from droidrun.agent.tool_registry import ToolRegistry
45
48
  from droidrun.agent.trajectory import TrajectoryWriter
49
+ from droidrun.agent.utils.actions import complete, open_app, remember
46
50
  from droidrun.agent.utils.llm_loader import (
47
51
  load_agent_llms,
48
52
  merge_llms_with_config,
@@ -52,8 +56,11 @@ from droidrun.agent.utils.signatures import (
52
56
  ATOMIC_ACTION_SIGNATURES,
53
57
  build_credential_tools,
54
58
  )
55
- from droidrun.agent.utils.actions import open_app, remember, complete
56
- from droidrun.agent.utils.tracing_setup import setup_tracing
59
+ from droidrun.agent.utils.tracing_setup import (
60
+ apply_session_context,
61
+ record_langfuse_screenshot,
62
+ setup_tracing,
63
+ )
57
64
  from droidrun.agent.utils.trajectory import Trajectory
58
65
  from droidrun.config_manager.config_manager import (
59
66
  AgentConfig,
@@ -66,24 +73,19 @@ from droidrun.config_manager.config_manager import (
66
73
  TracingConfig,
67
74
  )
68
75
  from droidrun.config_manager.safe_execution import SafeExecutionConfig
69
- from droidrun.credential_manager import FileCredentialManager, CredentialManager
70
- from droidrun.mcp.config import MCPConfig
71
- from droidrun.mcp.client import MCPClientManager
76
+ from droidrun.credential_manager import CredentialManager, FileCredentialManager
77
+ from droidrun.log_handlers import CLILogHandler, configure_logging
72
78
  from droidrun.mcp.adapter import mcp_to_droidrun_tools
79
+ from droidrun.mcp.client import MCPClientManager
80
+ from droidrun.mcp.config import MCPConfig
73
81
  from droidrun.telemetry import (
74
82
  DroidAgentFinalizeEvent,
75
83
  DroidAgentInitEvent,
76
84
  capture,
77
85
  flush,
78
86
  )
79
- from droidrun.agent.external import load_agent
80
- from droidrun.agent.utils.tracing_setup import (
81
- apply_session_context,
82
- record_langfuse_screenshot,
83
- )
84
- from async_adbutils import adb
85
- from droidrun.log_handlers import CLILogHandler, configure_logging
86
87
  from droidrun.tools.driver.android import AndroidDriver
88
+ from droidrun.tools.driver.base import DeviceDisconnectedError
87
89
  from droidrun.tools.driver.ios import IOSDriver
88
90
  from droidrun.tools.driver.recording import RecordingDriver
89
91
  from droidrun.tools.driver.stealth import StealthDriver
@@ -91,7 +93,6 @@ from droidrun.tools.filters import ConciseFilter, DetailedFilter
91
93
  from droidrun.tools.formatters import IndexedFormatter
92
94
  from droidrun.tools.ui.ios_provider import IOSStateProvider
93
95
  from droidrun.tools.ui.provider import AndroidStateProvider
94
- from opentelemetry import trace
95
96
 
96
97
  if TYPE_CHECKING:
97
98
  from droidrun.tools.driver.base import DeviceDriver
@@ -533,7 +534,10 @@ class DroidAgent(Workflow):
533
534
  self.executor_agent.registry = self.registry
534
535
  self.executor_agent.action_ctx = self.action_ctx
535
536
 
536
- # ── 6. External agent mode ────────────────────────────────────
537
+ # ── 6. Fetch device date once ─────────────────────────────────
538
+ self.shared_state.device_date = await driver.get_date()
539
+
540
+ # ── 7. External agent mode ────────────────────────────────────
537
541
  if self._using_external_agent:
538
542
  agent_name = self.config.agent.name
539
543
  agent_module = load_agent(agent_name)
@@ -644,6 +648,14 @@ class DroidAgent(Workflow):
644
648
  instruction=ev.instruction,
645
649
  )
646
650
 
651
+ except DeviceDisconnectedError as e:
652
+ logger.error(f"Device disconnected: {e}")
653
+ return FastAgentResultEvent(
654
+ success=False,
655
+ reason=f"Device disconnected: {e}",
656
+ instruction=ev.instruction,
657
+ )
658
+
647
659
  except Exception as e:
648
660
  logger.error(f"Error during task execution: {e}")
649
661
  if self.config.logging.debug:
@@ -689,12 +701,16 @@ class DroidAgent(Workflow):
689
701
  f"🔄 Step {self.shared_state.step_number}/{self.config.agent.max_steps}"
690
702
  )
691
703
 
692
- handler = self.manager_agent.run()
704
+ try:
705
+ handler = self.manager_agent.run()
693
706
 
694
- async for nested_ev in handler.stream_events():
695
- self.handle_stream_event(nested_ev, ctx)
707
+ async for nested_ev in handler.stream_events():
708
+ self.handle_stream_event(nested_ev, ctx)
696
709
 
697
- result = await handler
710
+ result = await handler
711
+ except DeviceDisconnectedError as e:
712
+ logger.error(f"Device disconnected: {e}")
713
+ return FinalizeEvent(success=False, reason=f"Device disconnected: {e}")
698
714
 
699
715
  event = ManagerPlanEvent(
700
716
  plan=result["plan"],
@@ -22,6 +22,7 @@ class DroidAgentState(BaseModel):
22
22
  # ========================================================================
23
23
  # Device State (current)
24
24
  # ========================================================================
25
+ device_date: str = "" # Fetched once at startup
25
26
  formatted_device_state: str = "" # Text description for prompts
26
27
  focused_text: str = "" # Text in focused input field
27
28
  a11y_tree: List[Dict] = Field(default_factory=list) # Raw accessibility tree
@@ -10,14 +10,15 @@ This agent is responsible for:
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import copy
13
14
  import json
14
15
  import logging
15
16
  from typing import TYPE_CHECKING, Optional, Type
16
17
 
17
18
  from llama_index.core.llms.llm import LLM
18
19
  from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
19
- from pydantic import BaseModel
20
20
  from opentelemetry import trace
21
+ from pydantic import BaseModel
21
22
 
22
23
  from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
23
24
  from droidrun.agent.manager.events import (
@@ -28,21 +29,21 @@ from droidrun.agent.manager.events import (
28
29
  from droidrun.agent.manager.prompts import parse_manager_response
29
30
  from droidrun.agent.usage import get_usage_from_response
30
31
  from droidrun.agent.utils.chat_utils import (
31
- to_chat_messages,
32
32
  filter_empty_messages,
33
+ to_chat_messages,
33
34
  )
34
- import copy
35
35
  from droidrun.agent.utils.inference import acall_with_retries
36
- from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
37
36
  from droidrun.agent.utils.prompt_resolver import PromptResolver
37
+ from droidrun.agent.utils.signatures import ATOMIC_ACTION_SIGNATURES
38
+ from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
38
39
  from droidrun.app_cards.app_card_provider import AppCardProvider
39
40
  from droidrun.app_cards.providers import (
40
41
  CompositeAppCardProvider,
41
42
  LocalAppCardProvider,
42
43
  ServerAppCardProvider,
43
44
  )
44
- from droidrun.agent.utils.signatures import ATOMIC_ACTION_SIGNATURES
45
45
  from droidrun.config_manager.prompt_loader import PromptLoader
46
+ from droidrun.tools.driver.base import DeviceDisconnectedError
46
47
 
47
48
  if TYPE_CHECKING:
48
49
  from droidrun.agent.action_context import ActionContext
@@ -187,9 +188,7 @@ class ManagerAgent(Workflow):
187
188
 
188
189
  variables = {
189
190
  "instruction": self.shared_state.instruction,
190
- "device_date": (
191
- await self.action_ctx.driver.get_date() if self.action_ctx else ""
192
- ),
191
+ "device_date": self.shared_state.device_date,
193
192
  "app_card": self.shared_state.app_card,
194
193
  "important_notes": "", # TODO: implement
195
194
  "error_history": error_history,
@@ -430,6 +429,8 @@ class ManagerAgent(Workflow):
430
429
  vision_enabled=self.vision,
431
430
  )
432
431
  logger.debug("📸 Screenshot captured for Manager")
432
+ except DeviceDisconnectedError:
433
+ raise
433
434
  except Exception as e:
434
435
  logger.warning(f"Failed to capture screenshot: {e}")
435
436
 
@@ -9,8 +9,8 @@ from typing import TYPE_CHECKING, Optional, Type
9
9
 
10
10
  from llama_index.core.llms.llm import LLM
11
11
  from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
12
- from pydantic import BaseModel
13
12
  from opentelemetry import trace
13
+ from pydantic import BaseModel
14
14
 
15
15
  from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
16
16
  from droidrun.agent.manager.events import (
@@ -22,9 +22,10 @@ from droidrun.agent.manager.prompts import parse_manager_response
22
22
  from droidrun.agent.usage import get_usage_from_response
23
23
  from droidrun.agent.utils.chat_utils import to_chat_messages
24
24
  from droidrun.agent.utils.inference import acall_with_retries
25
- from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
26
25
  from droidrun.agent.utils.prompt_resolver import PromptResolver
26
+ from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
27
27
  from droidrun.config_manager.prompt_loader import PromptLoader
28
+ from droidrun.tools.driver.base import DeviceDisconnectedError
28
29
 
29
30
  if TYPE_CHECKING:
30
31
  from droidrun.agent.action_context import ActionContext
@@ -90,9 +91,7 @@ class StatelessManagerAgent(Workflow):
90
91
  async def _build_prompt(self, has_text_to_modify: bool) -> str:
91
92
  variables = {
92
93
  "instruction": self.shared_state.instruction,
93
- "device_date": (
94
- await self.action_ctx.driver.get_date() if self.action_ctx else ""
95
- ),
94
+ "device_date": self.shared_state.device_date,
96
95
  "previous_plan": self.shared_state.previous_plan,
97
96
  "previous_state": self.shared_state.previous_formatted_device_state,
98
97
  "memory": self.shared_state.manager_memory,
@@ -211,6 +210,8 @@ class StatelessManagerAgent(Workflow):
211
210
  ),
212
211
  vision_enabled=self.vision,
213
212
  )
213
+ except DeviceDisconnectedError:
214
+ raise
214
215
  except Exception as e:
215
216
  logger.warning(f"Failed to capture screenshot: {e}")
216
217
 
@@ -1,13 +1,14 @@
1
1
  """Device driver abstractions for DroidRun."""
2
2
 
3
3
  from droidrun.tools.driver.android import AndroidDriver
4
- from droidrun.tools.driver.base import DeviceDriver
4
+ from droidrun.tools.driver.base import DeviceDisconnectedError, DeviceDriver
5
5
  from droidrun.tools.driver.cloud import CloudDriver
6
6
  from droidrun.tools.driver.ios import IOSDriver
7
7
  from droidrun.tools.driver.recording import RecordingDriver
8
8
  from droidrun.tools.driver.stealth import StealthDriver
9
9
 
10
10
  __all__ = [
11
+ "DeviceDisconnectedError",
11
12
  "DeviceDriver",
12
13
  "AndroidDriver",
13
14
  "CloudDriver",
@@ -9,6 +9,12 @@ from __future__ import annotations
9
9
  from typing import Any, Dict, List, Optional
10
10
 
11
11
 
12
+ class DeviceDisconnectedError(Exception):
13
+ """Raised when the device is no longer reachable."""
14
+
15
+ pass
16
+
17
+
12
18
  class DeviceDriver:
13
19
  """Base class for all device drivers.
14
20
 
@@ -7,14 +7,17 @@ for cloud-hosted devices via the MobileRun API.
7
7
  from __future__ import annotations
8
8
 
9
9
  import logging
10
- from typing import Any, Dict, List, Optional
10
+ from typing import Any, Awaitable, Dict, List, Optional, TypeVar
11
11
 
12
12
  from mobilerun import AsyncMobilerun
13
+ from mobilerun._exceptions import APIConnectionError, APITimeoutError, ConflictError
13
14
 
14
- from droidrun.tools.driver.base import DeviceDriver
15
+ from droidrun.tools.driver.base import DeviceDisconnectedError, DeviceDriver
15
16
 
16
17
  logger = logging.getLogger("droidrun")
17
18
 
19
+ T = TypeVar("T")
20
+
18
21
 
19
22
  class CloudDriver(DeviceDriver):
20
23
  """Cloud device I/O via the MobileRun SDK."""
@@ -52,6 +55,7 @@ class CloudDriver(DeviceDriver):
52
55
  api_key="x",
53
56
  base_url=base_url,
54
57
  timeout=10.0,
58
+ max_retries=4,
55
59
  default_headers={"X-User-ID": user_id},
56
60
  )
57
61
  else:
@@ -59,6 +63,7 @@ class CloudDriver(DeviceDriver):
59
63
  api_key=api_key,
60
64
  base_url=base_url,
61
65
  timeout=10.0,
66
+ max_retries=4,
62
67
  )
63
68
 
64
69
  @property
@@ -66,6 +71,13 @@ class CloudDriver(DeviceDriver):
66
71
  """Common keyword arg for display routing."""
67
72
  return {"x_device_display_id": self.display_id}
68
73
 
74
+ async def _call(self, coro: Awaitable[T]) -> T:
75
+ """Await an SDK coroutine, translating disconnect errors."""
76
+ try:
77
+ return await coro
78
+ except (ConflictError, APIConnectionError, APITimeoutError) as e:
79
+ raise DeviceDisconnectedError(str(e)) from e
80
+
69
81
  # -- lifecycle -----------------------------------------------------------
70
82
 
71
83
  async def connect(self) -> None:
@@ -77,8 +89,10 @@ class CloudDriver(DeviceDriver):
77
89
  # -- input actions -------------------------------------------------------
78
90
 
79
91
  async def tap(self, x: int, y: int) -> None:
80
- await self._client.devices.actions.tap(
81
- self.device_id, x=x, y=y, **self._display_kw
92
+ await self._call(
93
+ self._client.devices.actions.tap(
94
+ self.device_id, x=x, y=y, **self._display_kw
95
+ )
82
96
  )
83
97
 
84
98
  async def swipe(
@@ -89,25 +103,25 @@ class CloudDriver(DeviceDriver):
89
103
  y2: int,
90
104
  duration_ms: float = 1000,
91
105
  ) -> None:
92
- await self._client.devices.actions.swipe(
93
- self.device_id,
94
- start_x=x1,
95
- start_y=y1,
96
- end_x=x2,
97
- end_y=y2,
98
- duration=duration_ms,
99
- **self._display_kw,
106
+ await self._call(
107
+ self._client.devices.actions.swipe(
108
+ self.device_id,
109
+ start_x=x1,
110
+ start_y=y1,
111
+ end_x=x2,
112
+ end_y=y2,
113
+ duration=duration_ms,
114
+ **self._display_kw,
115
+ )
100
116
  )
101
117
 
102
118
  async def input_text(self, text: str, clear: bool = False) -> bool:
103
- try:
104
- await self._client.devices.keyboard.write(
119
+ await self._call(
120
+ self._client.devices.keyboard.write(
105
121
  self.device_id, text=text, clear=clear, **self._display_kw
106
122
  )
107
- return True
108
- except Exception as e:
109
- logger.error(f"Failed to input text: {e}")
110
- return False
123
+ )
124
+ return True
111
125
 
112
126
  async def press_key(self, keycode: int) -> None:
113
127
  # Map Android keycodes to MobileRun global actions where needed
@@ -116,8 +130,10 @@ class CloudDriver(DeviceDriver):
116
130
  elif keycode == 3: # KEYCODE_HOME
117
131
  await self.global_action(self._GLOBAL_HOME)
118
132
  else:
119
- await self._client.devices.keyboard.key(
120
- self.device_id, key=keycode, **self._display_kw
133
+ await self._call(
134
+ self._client.devices.keyboard.key(
135
+ self.device_id, key=keycode, **self._display_kw
136
+ )
121
137
  )
122
138
 
123
139
  async def drag(
@@ -133,67 +149,56 @@ class CloudDriver(DeviceDriver):
133
149
  # -- app management ------------------------------------------------------
134
150
 
135
151
  async def start_app(self, package: str, activity: Optional[str] = None) -> str:
136
- try:
137
- await self._client.devices.apps.start(
152
+ await self._call(
153
+ self._client.devices.apps.start(
138
154
  package,
139
155
  device_id=self.device_id,
140
156
  activity=activity or None,
141
157
  **self._display_kw,
142
158
  )
143
- return f"App started: {package}"
144
- except Exception as e:
145
- return f"Failed to start app {package}: {e}"
159
+ )
160
+ return f"App started: {package}"
146
161
 
147
162
  async def get_apps(self, include_system: bool = True) -> List[Dict[str, Any]]:
148
- try:
149
- apps = await self._client.devices.apps.list(
163
+ apps = await self._call(
164
+ self._client.devices.apps.list(
150
165
  device_id=self.device_id,
151
166
  include_system_apps=include_system,
152
167
  **self._display_kw,
153
168
  )
154
- return [app.model_dump() for app in apps]
155
- except Exception as e:
156
- logger.error(f"Failed to get apps: {e}")
157
- return []
169
+ )
170
+ return [app.model_dump() for app in apps]
158
171
 
159
172
  async def list_packages(self, include_system: bool = False) -> List[str]:
160
- try:
161
- packages = await self._client.devices.packages.list(
173
+ packages = await self._call(
174
+ self._client.devices.packages.list(
162
175
  device_id=self.device_id,
163
176
  include_system_packages=include_system,
164
177
  **self._display_kw,
165
178
  )
166
- return packages
167
- except Exception as e:
168
- logger.error(f"Failed to list packages: {e}")
169
- return []
179
+ )
180
+ return packages
170
181
 
171
182
  # -- state / observation -------------------------------------------------
172
183
 
173
184
  async def screenshot(self, hide_overlay: bool = True) -> bytes:
174
- try:
175
- response = await self._client.devices.state.with_raw_response.screenshot(
185
+ response = await self._call(
186
+ self._client.devices.state.with_raw_response.screenshot(
176
187
  self.device_id, **self._display_kw
177
188
  )
178
- return await response.read()
179
- except Exception as e:
180
- logger.error(f"Failed to capture screenshot: {e}")
181
- return b""
189
+ )
190
+ return await self._call(response.read())
182
191
 
183
192
  async def get_ui_tree(self) -> Dict[str, Any]:
184
- response = await self._client.devices.state.ui(
185
- self.device_id, **self._display_kw
193
+ response = await self._call(
194
+ self._client.devices.state.ui(self.device_id, **self._display_kw)
186
195
  )
187
196
  return response.model_dump()
188
197
 
189
198
  async def get_date(self) -> str:
190
- try:
191
- return await self._client.devices.state.time(
192
- self.device_id, **self._display_kw
193
- )
194
- except Exception as e:
195
- logger.error(f"Failed to get date: {e}")
196
- return "unknown"
199
+ return await self._call(
200
+ self._client.devices.state.time(self.device_id, **self._display_kw)
201
+ )
197
202
 
198
203
  # -- cloud-specific ------------------------------------------------------
199
204
 
@@ -203,11 +208,9 @@ class CloudDriver(DeviceDriver):
203
208
  Common actions: 1=Back, 2=Home, 3=Recents, 4=Notifications,
204
209
  5=QuickSettings, 6=PowerDialog, 9=TakeScreenshot.
205
210
  """
206
- try:
207
- await self._client.devices.actions.global_(
211
+ await self._call(
212
+ self._client.devices.actions.global_(
208
213
  self.device_id, action=action, **self._display_kw
209
214
  )
210
- return True
211
- except Exception as e:
212
- logger.error(f"Failed to execute global action {action}: {e}")
213
- return False
215
+ )
216
+ return True