Quick Start
Setup, Smoke Tests, Batch Runs, and Metrics
This page mirrors the benchmark workflow in the repository: create the environment, run a smoke test, run a day of tasks, and aggregate MobileWorld-style metrics.
Environment Setup
Clone the repository and install dependencies. This repo is uv-managed end to end.
git clone https://github.com/YuvrajSingh-mist/AndroidLife.git
cd AndroidLife
uv sync --extra dev --extra tracing --extra hf
cp .env.example .env
OPENROUTER_API_KEY=... # needed if using OpenRouter (default agent host)
OPENAI_API_KEY=... # only needed for the ask_user tool (Hard/ASK USER tasks)
HF_TOKEN=hf_... # only needed for pushing dataset exports to Hugging Face
Prerequisites are system tools (not uv-managed): adb, scrcpy,
and Python 3.11–3.13. Every run writes into assets/runs/.
Smoke Test
Confirm the phone and model server are reachable, then run the pre-flight check before any real
benchmark run (or after changing phones/model hosts). It checks prerequisites, the LLM server
(GET /models + a real chat completion), wired and wireless ADB with a device health
check, and one real one-step agent run:
adb devices -l
curl -s "$LLM_UPSTREAM/models"
./scripts/run/smoke_test.sh --help # full flag reference
./scripts/run/smoke_test.sh # defaults: first USB device + first model
./scripts/run/smoke_test.sh --llm-url http://192.168.1.50:8080/v1 --model my-model
./scripts/run/smoke_test.sh --skip-llm --skip-agent-run --wireless-serial 192.168.1.23:5555
Running a Benchmark
Point LLM_UPSTREAM/MODEL at OpenRouter for a hosted model, or at a local
host. List a task slice first, then dry-run it to see the exact commands that would execute, then
run it for real:
export ANDROIDLIFE_SERIAL=RS7XKZDI8HTOJNYL # adb serial of your phone
export LLM_UPSTREAM=https://openrouter.ai/api
export MODEL='qwen/qwen3.7-flash'
uv run androidlife_tasks.py --bucket easy --app gmail --list
uv run androidlife_tasks.py \
--bucket easy --app gmail --skip-unresolved \
--serial "$ANDROIDLIFE_SERIAL" \
--llm-upstream-base "$LLM_UPSTREAM" --model "$MODEL" \
--dry-run
Run a whole day from the 28-day schedule (or all 530) with one command:
uv run python scripts/run/run_day.py --day 1
uv run python scripts/run/run_day.py --day 1 --dry-run # preview the exact per-task commands
uv run python scripts/run/run_day.py --all # the whole 530-task set
# resume an interrupted batch in place:
uv run python scripts/run/run_day.py --day 1 \
--run-root assets/runs/full-bench/2026-08-09-153930 \
--resume-from medium__gallery__001
Single one-off task with full harness artifacts:
uv run androidlife_runner.py \
--serial "$ANDROIDLIFE_SERIAL" \
--label gmail-unread-count \
--llm-upstream-base "$LLM_UPSTREAM" \
--model "$MODEL" --temperature 0 --steps 50 \
--goal "Check how many unread emails are in the inbox"
Metrics
After a batch, aggregate the run folders into MobileWorld-style metrics (Success Rate with the ASK USER gate, Average Completion Steps, Average User Queries, and User Interaction Quality):
uv run scripts/eval/androidlife_report.py \
--runs assets/runs/full-bench/2026-08-09-153930/day1
uv run scripts/eval/androidlife_report.py \
--runs 'assets/runs/full-bench/2026-08-09-153930/day1' --cooldown-seconds 10
Preview This Site
The website is static and GitHub Pages-ready. Rebuild the task data and preview locally:
node website/tools/build_site_data.mjs # regenerate site_data.json from the datasets
cd website
python3 -m http.server 8000
# then open http://localhost:8000