Metadata-Version: 2.1
Name: appworld-sdk
Version: 0.1.7
Summary: Client SDK for App World — RL & Eval environments for Android apps
Author: App World Contributors
License: Apache-2.0
Project-URL: Homepage, https://github.com/anthropics/app-world
Project-URL: Documentation, https://github.com/anthropics/app-world#readme
Project-URL: Repository, https://github.com/anthropics/app-world
Project-URL: Issues, https://github.com/anthropics/app-world/issues
Keywords: android,reinforcement-learning,gymnasium,evaluation,mobile
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests<3.0,>=2.28
Requires-Dist: numpy<3.0,>=1.24
Requires-Dist: Pillow<12.0,>=9.0
Requires-Dist: gymnasium<2.0,>=0.29

# App World SDK

Lightweight Python client for the **App World** platform — RL training and evaluation on real Android apps, with a standard [Gymnasium](https://gymnasium.farama.org/) interface.

## Installation

```bash
pip install appworld-sdk
```

**Requirements:** Python >= 3.11

## Quick Start

```python
from appworld_sdk import AppWorldClient

client = AppWorldClient(api_key="YOUR_API_KEY", base_url="https://api.appworld.dev")

# Browse available tasks
tasks = client.list_tasks()

# Allocate device resources
env_info = client.create_environment(task_ids=["FennoteCreateNote"])
env_id = env_info["id"]

# Get a Gymnasium-compatible environment
env = client.make_env(env_id=env_id, env_type="eval")

# Run a task
obs, info = env.reset(task_name="FennoteCreateNote")
done = False
while not done:
    action = {"action_type": 0, "x": 0.5, "y": 0.5, "text": "", "direction": 0}
    obs, reward, terminated, truncated, info = env.step(action)
    done = terminated or truncated

env.close()
```

## Environment Types

| Type | Class | Actions | Use Case |
|------|-------|---------|----------|
| `"rl"` | `RemoteAppWorldEnv` | 5 discrete (tap, swipe, etc.) | RL training |
| `"eval"` | `RemoteAppWorldEvalEnv` | 7 (incl. text input) | Agent evaluation |

## Client-Side Eval with Custom Agents

Implement the `BaseAgent` protocol to run evaluations where LLM calls stay on your side — your model API key never leaves the local process.

```python
from appworld_sdk import AppWorldClient

class MyAgent:
    """Implement predict() — the SDK checks this via BaseAgent Protocol."""
    def predict(self, *, screenshot, goal, **kwargs) -> dict:
        # Your model inference here
        return {"action_type": 0, "x": 0.5, "y": 0.5, "text": "", "direction": 0}

client = AppWorldClient(api_key="YOUR_API_KEY", base_url="https://api.appworld.dev")
env_info = client.create_environment(task_ids=["FennoteCreateNote", "FennoteDeleteNote"])

result = client.run_local_eval(
    env_id=env_info["id"],
    tasks=["FennoteCreateNote", "FennoteDeleteNote"],
    agent=MyAgent(),
    max_steps=15,
)

print(f"Success rate: {result.success_rate:.0%}")
print(f"Avg steps: {result.avg_steps:.1f}")
```

## Server-Side Eval

Let the platform handle LLM calls:

```python
from appworld_sdk import AppWorldClient

client = AppWorldClient(api_key="YOUR_API_KEY", base_url="https://api.appworld.dev")
env_info = client.create_environment(task_ids=["FennoteCreateNote"])

result = client.run_eval(
    env_id=env_info["id"],
    tasks=["FennoteCreateNote"],
    model_provider="anthropic",
    model_api_key="YOUR_MODEL_KEY",
    model_name="claude-sonnet-4-20250514",
)
print(f"Success rate: {result.success_rate}")
```

## API Reference

### `AppWorldClient(api_key, base_url, timeout)`

| Method | Description |
|--------|-------------|
| `list_apps(**filters)` | List available apps |
| `list_tasks(**filters)` | List available tasks |
| `get_task(task_id)` | Get task details |
| `create_environment(task_ids, name)` | Allocate device resources |
| `delete_environment(env_id)` | Release resources |
| `make_env(env_id, env_type)` | Create Gymnasium env |
| `run_eval(...)` | Server-side evaluation |
| `run_local_eval(...)` | Client-side evaluation |

### Exceptions

| Exception | HTTP | Meaning |
|-----------|------|---------|
| `AppWorldError` | — | Base exception |
| `AppWorldAPIError` | any | Server returned an error |
| `EnvironmentNotReady` | 503 | Device not available |
| `SessionExpired` | 410 | Session closed or timed out |

## License

Apache 2.0 — see [LICENSE](LICENSE) for details.
