Remove unreachable back button handler in IOSDriver.press_button()
(guard rejects it before reaching the handler). Guard empty
supported_buttons producing malformed system_button description.
Update iOS docs to match current driver behavior: get_date() works,
input_text() clear is supported, swipe uses coordinates, port is 6643.
Replace stub iOS setup guide with full Xcode build/signing/iproxy
instructions.
- Implement auto-discovery of iOS portal using a port scanning method.
- Validate and normalize iOS portal URLs to ensure correct format.
- Update IOSDriver to handle connection errors more gracefully.
- Refactor tool registration to support platform-specific app opening methods.
- Improve error logging for better debugging and user feedback.
- Replace interactive-type whitelist with skip-type blacklist so all
visible elements (text, icons, images) appear in UI state
- Filter elements with zero width or height (not tappable)
- Label iOS elements as "Current UI elements" instead of "Clickable"
- Use effective package/activity in telemetry events
Use /state_full instead of separate /vision/a11y + /vision/state calls.
Add coordinate-based swipe, clear support in input_text, back button
via /gestures/back, and get_date via /device/date. Remove deprecated
_infer_screen_size in favor of device_context screen_bounds.
Skip the App line in formatted phone state when packageName is empty
(e.g., on iOS where there's no package concept). Prevent
update_current_app from overwriting known values with empty strings.
Replace scattered tool registration (ATOMIC_ACTION_SIGNATURES dict,
inline registrations in droid_agent.py, build_credential_tools()) with
a single build_tool_registry() function in signatures.py.
- Add platform property to DeviceDriver (Android/iOS), derived from
actual driver in start_handler instead of config
- Dynamic system_button description from driver.supported_buttons
- Replace hardcoded "Android" in prompt templates with {{ platform }}
- Gate available_secrets on type_secret being in registry
- Fix manager exclusion set bug (open_app/type_secret leaked into
custom_actions)
- Move telemetry init event to start_handler, use standard_tool_names
- Rename AppStarter tools param to driver
BREAKING CHANGE: `ATOMIC_ACTION_SIGNATURES` and `build_credential_tools`
are removed from the public API. Use `build_tool_registry()` instead.
Remove v3, v4, and v5 directories. Move latest (v5) docs to docs root.
Update docs.json navigation to use flat tabs instead of versioned layout.
Fix all internal links to use unversioned paths.
- Fix send_user_message example to use asyncio.create_task()
- Add description for --agent flag and external agents
- Document stealth and wpm params on input_text
- Fix fd leak in screenshot command (wrap os.write in try/finally)
- Check iOS flag before connecting in long-press command
- Remove dead except ValueError in press (click.Choice already validates)
- Move os import to top of file
Add `droidrun device` subgroup with 9 commands: screenshot, ui, tap,
swipe, long-press, type, press, apps, start. These bypass the LLM agent
and talk directly to the device driver.
Replace the Android-centric `press_key(keycode)` interface with a
platform-agnostic `press_button(name)` abstraction across all drivers
(Android, iOS, Cloud, Stealth, Recording). Each driver declares its own
`supported_buttons` set and maps button names internally.
Remove `DroidRunCLI` auto-routing that implicitly routed unknown args
to the `run` command.
BREAKING CHANGE: `DeviceDriver.press_key(keycode)` is removed in favor
of `DeviceDriver.press_button(button)`. Macro recordings now emit
`button_press` action type instead of `key_press`.
- Allow agents with no config section (use DEFAULT_CONFIG or env vars)
- Validate run() is async, reject sync functions with clear error
- Wrap list_agents() at CLI import to prevent crashes on scan failure
- Simplify migration to only remove example entries
- Add README.md with full contract, AdbDevice API, and setup guide
External agents now receive a raw async_adbutils.AdbDevice instead of
internal DroidRun tools. This makes them fully self-contained — zero
imports from droidrun, just copy-paste a file or folder and it works.
- Remove mai_ui and autoglm agents (depended on internals)
- Pass raw AdbDevice directly, skip Portal/driver/registry setup
- Add --agent CLI flag with dynamic discovery from external/ dir
- Add list_agents() for runtime agent enumeration
- Add config migration v005 to clean up legacy agent entries
- Update config_example.yaml to remove old agent references
BREAKING CHANGE: external agent run() signature changed from
(tools, instruction, config, max_steps) to
(device, instruction, config, max_steps) where device is an
async_adbutils.AdbDevice
Remove three deprecated agents and all associated dead code:
- CodeActAgent (Python code-gen + exec)
- ScripterAgent (off-device Python execution)
- TextManipulatorAgent (text field editing via code-gen)
Only FastAgent (XML tool-calling) remains as the direct-execution
agent. Rename agent/codeact/ to agent/fast_agent/ and
config/prompts/codeact/ to config/prompts/fast_agent/.
Also removes: SimpleCodeExecutor, SafeExecutionConfig,
extract_code_and_thought, code_checker, and all related config
fields (codeact, scripter, text_manipulator LLM profiles).
Adds v004 config migration to strip removed keys and update
prompt paths in existing user configs.
BREAKING CHANGE: `ScripterConfig`, `SafeExecutionConfig`, and
`codeact` config field are removed. The `text_manipulator` and
`scripter` LLM profiles are no longer used. Users with custom
imports of these classes or configs referencing removed fields
will need to update their code.
- Set _RECOVERY_AFTER_ATTEMPT to 5 so recovery fires after ~11s as intended
- Use Optional[List[float]] consistently instead of mixing old/new style hints
- Simplify nested f-string in retry warning log
- Update docstring to reflect actual fallback behavior for short delay lists
Restart Portal's TCP socket server alongside the accessibility service
during mid-retry recovery. This handles the case where the TCP server
crashes mid-run, causing state requests to fail on both TCP and content
provider paths.
Extract retry logic into fetch_state_with_retry() helper with 7 attempts,
increasing backoff (1-10s, ~29s total), and mid-retry accessibility service
restart after ~11s of failures. Fixes intermittent "Portal returned error:
Unknown error" by logging the full Portal response dict.
CloudDriver.__init__ accepts stealth=True which passes
{"stealth": true} via extra_body on tap, swipe, and input_text
calls to devices-api. No stealth logic added — purely passthrough.
- Manager and StatelessManager now emit ScreenshotEvent before
RecordUIStateEvent, matching FastAgent/CodeAct ordering
- DroidAgent finalize step now emits RecordUIStateEvent after the
final screenshot so every screenshot has a paired UI state