# FastVM Provider

OSWorld `--provider_name fastvm` runs tasks on [FastVM](https://fastvm.org)
microVMs via the public FastVM API. Every episode restores from a snapshot
in seconds, not minutes.

## Quickstart

```bash
# 1. Install the SDK
pip install fastvm

# 2. Get an API key (https://fastvm.org/dashboard → API keys)
export FASTVM_API_KEY=hlm_...

# 3. Bake the OSWorld guest image — one-time, ~5 min for minimal, ~30–45 min for full
python scripts/fastvm/bake_image.py --mode minimal --name osworld-minimal-v1
#   => prints: export FASTVM_OSWORLD_SNAPSHOT_ID=<uuid>

# 4. Export the id the bake prints
export FASTVM_OSWORLD_SNAPSHOT_ID=<uuid>

# 5. Run OSWorld
python quickstart.py --provider_name fastvm --headless true
```

Once baked, every subsequent episode reuses the snapshot — cold start is
~0.5–1 s and carries no per-test bake cost.

### Why the bake step exists

AWS and Docker providers skip it because their images are **publicly
distributed** (a public AMI and a Docker Hub image respectively). FastVM
snapshots are org-scoped today, so the image has to be baked inside the
customer's own org. A proposal to add public snapshots — which would
eliminate this step and match AWS's zero-setup UX — is tracked at
[fastvm-mono/docs/proposal-public-snapshots.md](../../../fastvm-mono/docs/proposal-public-snapshots.md).

## Bake modes

| mode      | wall-clock | covers                                                               | good for                               |
|-----------|------------|----------------------------------------------------------------------|----------------------------------------|
| `minimal` | ~1.5 min   | Xvfb + `osworld_server` on `:5000`                                   | quickstart smoke, control-plane perf   |
| `full`    | ~4.5 min   | above + XFCE + Chromium/Chrome + LibreOffice + VSCode + VLC + noVNC  | real benchmark runs, multi_apps tasks  |

### Measured bake times on `api.fastvm.org` (c4m8, 40 GiB disk)

```
full:
  launch              4.1s
  upload              3.5s
  install           240.9s   (apt VS Code/LibreOffice/GIMP/VLC/Thunderbird + session config)
  verify_external     0.5s
  snapshot           25.2s
  total             274.3s
```

After the bake, snapshot restore is seconds rather than minutes (compare AWS
`create_image` + `RunInstances` cycle, which is minutes to tens of minutes).

Artifacts of a bake are at [scripts/fastvm/](../../../scripts/fastvm/):
`install_osworld_minimal.sh`, `install_osworld_full.sh`, `bake_image.py`.

## Environment variables

| Variable                      | Required  | Default                  | Purpose                                                              |
|-------------------------------|-----------|--------------------------|----------------------------------------------------------------------|
| `FASTVM_API_KEY`              | yes       | —                        | Bearer token (`hlm_...`)                                             |
| `FASTVM_BASE_URL`             | no        | `https://api.fastvm.org` | API endpoint                                                         |
| `FASTVM_OSWORLD_SNAPSHOT_ID`  | yes\*     | —                        | Snapshot id from the bake step                                       |
| `FASTVM_MACHINE_TYPE`         | no        | `c4m8`                   | Fresh-boot shape when no snapshot id is set                          |
| `FASTVM_DISK_GIB`             | no        | inherit                  | Disk override (GiB)                                                  |
| `FASTVM_LAUNCH_TIMEOUT_SEC`   | no        | `300`                    | VM status=running wait budget                                        |
| `FASTVM_READY_TIMEOUT_SEC`    | no        | `300`                    | In-VM `:5000` probe wait budget                                      |
| `FASTVM_SKIP_READY_CHECK`     | no        | —                        | `1` skips the `:5000` probe (control-plane smoke testing only)       |

\* Not strictly required to *instantiate* the provider — but without a
baked OSWorld snapshot the `:5000` readiness probe will time out.

## Smoke test (control plane only, no bake required)

```bash
FASTVM_SKIP_READY_CHECK=1 FASTVM_MACHINE_TYPE=c1m2 \
  python -m desktop_env.providers.fastvm.smoke_test
```

Exercises launch → IP → snapshot → revert → delete against the default
FastVM image. Typical timings:

```
launch               0.5s
get_ip               0.0s
snapshot             1.0s
revert               0.7s
```

For comparison: AWS instance boot is ~60–90 s; AWS `create_image` takes
minutes. FastVM's order-of-magnitude advantage on restore is the whole
reason OSWorld on FastVM is interesting.

## Limitations / caveats

- **Public IPv6 only.** FastVM hands out public IPv6 for VM ingress. The
  machine running `DesktopEnv` needs v6 reachability (`curl -6 ifconfig.co`
  confirms). If v6 is unavailable, run the OSWorld controller from a v6
  host (GCP, Linode, Fly.io, Cloudflare Tunnel).
- **Firewall defaults to `mode=open`.** Fine for the trial demo; switch to
  `restricted` + explicit IPv6 CIDRs before handing credentials to anyone.
- **`os_type` is ignored.** FastVM's image catalogue is selected via
  `snapshot_id`; there's no Windows/Ubuntu switch at launch time.
- **Screen size is baked into the guest image.** Changing
  `SCREEN_WIDTH`/`SCREEN_HEIGHT` env vars won't reshape a running VM; the
  image builds with `1920×1080` (matches the OSWorld AWS AMI).
- **`full` mode uses Debian 12 + XFCE**, not Ubuntu 22.04 + GNOME like the
  upstream README. Tasks that hard-assume GNOME-specific paths (dconf
  schemas, gsettings keys) may need per-task tweaks. Tracked for a v2 image.
