jev-mobile
Control Android and HarmonyOS devices with bounded, inspectable natural-language agent loops powered by TypeSafe/Jev.
jev-mobile observes the current UI hierarchy, preserves visible information, asks Jev to select one typed action, validates that action against the latest snapshot, and executes it through ADB or HDC. Device access, retries, stopping rules, and side effects remain under deterministic Python control.
https://github.com/user-attachments/assets/076bfab8-3d0e-49c8-9f6d-acec0fdbc643
https://github.com/user-attachments/assets/b6538548-2299-4075-8e64-c6003e55e8a7
Open the editable Excalidraw source.
Highlights
- Android support through ADB and HarmonyOS support through HDC.
- Platform-neutral UI snapshots containing actionable elements and visible static text.
- A bounded action set: start app, click, long-click, swipe, type, wait, hand off, or finish.
- Revisioned snapshots that reject stale element references after the UI changes.
- Configurable confidence thresholds, retry limits, and human handoff.
- No unrestricted shell access exposed to the model.
- Unit tests run without a physical device or live TypeSafe request.
How It Works
- Capture the foreground app and its UI hierarchy.
- Normalize platform-specific nodes into a shared element model.
- Send the goal, visible text, recent actions, and bounded choices to Jev.
- Validate the selected action and target against the current snapshot.
- Execute through the platform adapter, then observe the UI again.
Static text is included as observation context but is never offered as an action target unless the underlying element is enabled and supports that action.
Requirements
uv- A TypeSafe API key
- A connected Android device with
adb, or a HarmonyOS device withhdc - Python 3.10 or newer, managed automatically by
uvwhen needed
Set your TypeSafe API key:
export TYPESAFE_API_KEY='<your TypeSafe API key>'
The CLI checks authentication before accessing the device.
Install and Run
Run jev-mobile directly with uvx. It installs the package in an isolated environment and reuses the cached installation on later runs:
uvx jev-mobile run --help
No repository clone or project virtual environment is required for CLI usage.
Usage
Important: Jev does not generate text. The CLI does not extract or invent text values from the task description. When a task requires typing into an editable field but no explicit value is available, the agent stops automatic interaction and requests human handoff. Follow the terminal's
HANDOFFreason andACTIONinstruction, enter the text directly on the device, then press Enter so the agent can observe the UI again and continue.
Give the agent both a task and an observable completion condition. This makes finishing behavior more reliable than a goal such as "open Settings" alone.
Android
uvx jev-mobile run \
"Open Settings and view battery information." \
--platform android \
--device emulator-5554
HarmonyOS
uvx jev-mobile run \
"Open Settings and view battery information." \
--platform harmonyos \
--device 127.0.0.1:5557
The --device option is optional when ADB or HDC can select the intended device by default.
HarmonyOS App Allowlist
HarmonyOS normally discovers launchable apps from installed bundle metadata. Discovery includes enabled PAGE abilities registered for the home screen and selects the bundle's declared main element when several abilities match.
Use --app BUNDLE/ABILITY[=LABEL] to replace discovery with an explicit allowlist. Repeat the option when the task may open more than one app:
uvx jev-mobile run \
"Open Settings and view battery information." \
--platform harmonyos \
--device 127.0.0.1:5557 \
--app com.huawei.hmos.settings/com.huawei.hmos.settings.MainAbility=Settings
Confidence and Handoff
Confidence values are probabilities between 0 and 1. For example:
uvx jev-mobile run \
"Open Settings and view battery information." \
--platform android \
--device emulator-5554 \
--action-confidence 0.2 \
--argument-confidence 0.5 \
--finish-confidence 0.9
| Option | Meaning | Default |
|---|---|---|
--action-confidence |
Minimum confidence for the next action | 0 |
--argument-confidence |
Minimum confidence for an element target or text value | 0 |
--finish-confidence |
Minimum confidence required to declare completion | 0 |
--uncertain-retries |
Re-observations before returning that human action is needed | 1 |
--reobserve-delay |
Seconds between uncertainty retries | 1 |
The agent invokes interactive human handoff only when Jev explicitly selects handoff or handoff_text_input as the next action. Click, long-click, and text-input actions no longer run through a separate risk judgment that can trigger handoff. During an interactive handoff, complete the requested action on the device and press Enter to continue. Exhausted uncertainty retries or a missing app match only return needs_handoff; they do not open an interactive prompt. Use --no-handoff to make explicit handoff actions return immediately as well.
Text input follows the same handoff flow. Jev can only select from bounded text values supplied explicitly by code; it cannot generate usernames, search terms, verification codes, or other free-form text. The current CLI has no option for supplying text values, so a required text-entry step prints a prompt similar to this:
HANDOFF Text input is required, but no text value was provided and Jev cannot generate one.
ACTION Enter the required text in the visible field on the device, then return.
Press Enter after completing the action on the device:
Python API callers can provide AgentTextInput candidates through AgentTask.text_inputs; only then may the agent execute type_text automatically. Values marked as sensitive are not sent to Jev. With --no-handoff, the CLI does not wait for input and returns exit code 3 instead.
CLI Reference
uvx jev-mobile run --help
Important run options:
| Option | Description |
|---|---|
--platform {android,harmonyos} |
Required device platform |
--device DEVICE |
ADB serial or HDC connect key |
--app BUNDLE/ABILITY[=LABEL] |
HarmonyOS launch allowlist entry; repeatable |
--adb-path PATH |
ADB executable path |
--hdc-path PATH |
HDC executable path |
--timeout SECONDS |
Device command timeout; default 15 |
--max-steps COUNT |
Maximum agent steps; default 30 |
--no-handoff |
Exit instead of prompting for human action |
Exit Codes
| Code | Meaning |
|---|---|
0 |
Task completed |
1 |
Agent or device operation failed |
2 |
CLI or configuration error |
3 |
Human action is required |
4 |
Step limit reached |
130 |
Interrupted by the user |
Development
From a repository checkout:
uv sync
uv run pytest
Build distribution artifacts with:
uv build
Platform integrations should remain behind adapters, and tests should use sanitized hierarchy fixtures, fake adapters, and mocked Jev responses rather than requiring real devices or API credentials.
Contributing
Issues and focused pull requests are welcome. Please include tests for behavior changes and keep device-, app-, locale-, and account-specific assumptions out of reusable package code.
Metadata
Release files for jev-mobile 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jev_mobile-0.1.0.tar.gz | 45.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jev_mobile-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.6 kB
Release files / jev_mobile-0.1.0.tar.gz
| Download URL | jev_mobile-0.1.0.tar.gz |
|---|---|
| Size | 45.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
95960531067b0948db27cdca6e9b61eca6a7b3b079eb93cb0b52f57e95f60bd6
|
|
BLAKE2b-256 checksum How to use checksums |
0ae750ce0b23f4e904ade056569e9c10a9857aef305779a948938e27f9524bc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / jev_mobile-0.1.0-py3-none-any.whl
| Download URL | jev_mobile-0.1.0-py3-none-any.whl |
|---|---|
| Size | 35.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d466dc18c353592fac9b86212e3c9aca9d2329b40f97be0e4efb1019b09188e2
|
|
BLAKE2b-256 checksum How to use checksums |
1c94cb5f91250012fccb5c04db88b47644fa2102c103850080a0f4008e614144
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|