Metadata-Version: 2.4
Name: eclise
Version: 0.2.0
Summary: Shared research infrastructure: clip/VLA contracts, research utilities, and stdlib launchers for isolated robotics/data environments.
Author: Wentinn Liao
License: MIT
Project-URL: Homepage, https://github.com/JophiArcana/eclise
Project-URL: Repository, https://github.com/JophiArcana/eclise
Project-URL: Issues, https://github.com/JophiArcana/eclise/issues
Keywords: research-utilities,robotics,vla,datasets,clips
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: utils
Requires-Dist: numpy; extra == "utils"
Requires-Dist: torch; extra == "utils"
Requires-Dist: tensordict; extra == "utils"
Requires-Dist: einops; extra == "utils"
Requires-Dist: scipy; extra == "utils"
Requires-Dist: matplotlib; extra == "utils"
Requires-Dist: tqdm; extra == "utils"
Requires-Dist: pandas; extra == "utils"
Provides-Extra: ode
Requires-Dist: torchdiffeq; extra == "ode"
Provides-Extra: imagenet
Requires-Dist: datasets<5.0,>=3.0; extra == "imagenet"
Requires-Dist: huggingface_hub<1.0,>=0.34.0; extra == "imagenet"
Requires-Dist: Pillow>=10; extra == "imagenet"
Requires-Dist: numpy>=1.24; extra == "imagenet"
Provides-Extra: clips
Requires-Dist: numpy>=1.24; extra == "clips"
Requires-Dist: h5py>=3.10; extra == "clips"
Requires-Dist: imageio[ffmpeg]>=2.36; extra == "clips"
Requires-Dist: av>=13.1; extra == "clips"
Provides-Extra: vla
Requires-Dist: numpy; extra == "vla"
Requires-Dist: websockets>=14; extra == "vla"
Requires-Dist: msgpack>=1.0.5; extra == "vla"
Provides-Extra: all
Requires-Dist: eclise[utils]; extra == "all"
Requires-Dist: eclise[imagenet]; extra == "all"
Requires-Dist: eclise[clips]; extra == "all"
Requires-Dist: eclise[vla]; extra == "all"
Provides-Extra: dev
Requires-Dist: eclise[all]; extra == "dev"
Requires-Dist: pytest~=8.4.0; extra == "dev"
Dynamic: license-file

# eclise

Shared research infrastructure: one `eclise` wheel under the PEP 420 namespace
`eclise.*`. Import path equals folder path equals taxonomy — one source tree
`src/eclise/`. Heavy stacks live in pixi environments, not in wheel metadata.

## Extras (the published wheel)

| Extra | Import | Purpose |
|---|---|---|
| `utils` | `eclise.utils` | Research utilities (tensor/module batching, linalg, ARE/ODE, labeled arrays, plotting) |
| `ode` | `eclise.utils.ode` | `torchdiffeq` for `batch_odeint` |
| `imagenet` | `eclise.datasets.imagenet` | Adapters for consuming external datasets (ImageNet-1k val sampling, label tables) |
| `clips` | `eclise.contracts.clips` | First-party clip-shard data contract (mp4-in-HDF5 + per-frame state labels) |
| `vla` | `eclise.contracts.vla` | Sim-/model-agnostic VLA obs/action schema + websocket env/policy serving |
| `all` | | utils + imagenet + clips + vla |
| `dev` | | all + pytest |

`eclise.models.{octo,smolvla,pi0}`, `eclise.sims.{libero,phyworld}`,
`eclise.datasets.openvid`, and `eclise.launch` ship as inert source in the
same wheel. Running a server or generator needs the matching pixi
environment (or `python -m eclise.launch`).

`models/vision/` is deliberately absent: a vision-model contract will be
created only once it has at least two real consumers.

## Pixi environments (from a checkout)

| Environment | Python | Kind | Purpose |
|---|---|---|---|
| `dev` | 3.12 | library | `eclise[dev]` + contract/launcher tests |
| `libero` | 3.10 | socket (env-server, port 9000) | LIBERO + robosuite/MuJoCo harness |
| `octo` | 3.10 | socket (policy, port 8000) | Octo JAX 0.4.20 policy server |
| `smolvla` | 3.12 | socket (policy, port 8000) | SmolVLA (LeRobot) policy server |
| `pi0` | 3.11 | socket (policy, port 8000) | Tooling for upstream openpi (`uv` / git-lfs / gsutil) |
| `phyworld` | 3.10 | batch | Box2D families → `eclise.contracts.clips` shards |
| `phyworld-phyre` | 3.9 | batch | PHYRE combinatorial family (`phyre==0.2.2`) |
| `openvid` | 3.10 | batch | OpenVid-1M mp4 → 256px fixed-FPS shards |

## Installing

Client-side (numpy-1.x-safe `eclise.contracts.vla` only — no torch/jax):

```bash
pip install "eclise[vla]"
python -m eclise.launch start octo --setup
```

`--setup` clones this repo at `eclise-v<wheel version>` (unless
`ECLISE_ROOT` already points at a checkout), installs pixi if needed, and
runs `pixi install -e <env>`. `start` returns a host/port; the caller wires
`WebsocketPolicyClient` / `WebsocketEnvClient`.

From a checkout:

```bash
pixi install -e dev
pixi run -e dev test
pixi run -e libero setup
pixi run -e libero serve --port 9000
```

## Developing

```bash
pixi run -e dev test
pixi run -e libero serve
pixi run -e phyworld generate --family collision --grid in_dist_l0 --experiment smoke --limit 32
python -m eclise.sims.phyworld generate --family collision --grid in_dist_l0 --experiment smoke --limit 32
```

Editable extras without pixi: `pip install -e ".[dev]"`. Releases are tagged
`eclise-v0.2.0`.

## Runtime data (`ECLISE_DATA_ROOT` / `$SCRATCH`)

Runtime trees (`data/`, `outputs/`, `logs/`) are not part of the source
taxonomy. `eclise.paths.data_root()` / `outputs_root()` resolve, in order:

1. `ECLISE_DATA_ROOT` / `ECLISE_OUTPUTS_ROOT` if set
2. `$SCRATCH/eclise/{data,outputs}` if `SCRATCH` is set
3. `<repo>/{data,outputs}`

Packages then pick a leaf (`data_root() / "phyworld"`,
`outputs_root() / "libero"`). On quota-capped hosts, set `SCRATCH` (or the
explicit `ECLISE_*_ROOT` vars) so large artifacts never land on the home
quota. There are no scratch-symlink setup tasks.

## Design rules

- **One distribution, environments at the pixi boundary.** Incompatible
  stacks (JAX vs torch, numpy 1.x vs 2.x) do not share an environment.
  Wheel extras stay light; pixi features own the heavy pins.
- **Import path == folder path == taxonomy.** Moving a package is a
  breaking import change; there is one tree and no alias extras.
- **`eclise.contracts.clips` and `eclise.contracts.vla` are contracts.**
  Writers and readers may live in different repos/envs; document schema
  changes in `CHANGELOG.md`. `eclise[vla]` must remain numpy 1.x-compatible.

## Package archetypes

Every package is one of three kinds. Archetype is recorded in the launcher
`kind` and the pixi feature shape, not in folders.

**Library extra** — published wheel, installed into a consumer's env, no
server. `utils`, `imagenet`, `clips`, `vla`.

**Interactive socket service** — pixi env isolates an incompatible stack
behind an `eclise.contracts.vla` websocket. `octo`, `smolvla`, `pi0`, `libero`.

- Env: `pixi install -e <name>` (and `pixi run -e <name> setup` when the
  feature defines a `setup` task).
- Server logic lives in the package; the CLI is
  `python -m eclise.<pkg> serve` (pi0 wraps upstream openpi instead).
- Launch: `python -m eclise.launch start <name>` → `pixi run -e <env> serve`.

**Batch producer** — pixi env; decoupled via the on-disk
`eclise.contracts.clips` shard contract (no socket). `phyworld`, `openvid`.

- Env: `pixi install -e <name>` (no scratch-symlink `setup` task).
- Job entrypoint: `python -m eclise.<pkg> <verb>` (+ `.sbatch` via
  `pixi run -e <env>`).

| Package | Archetype |
|---|---|
| `utils`, `imagenet`, `clips`, `vla` | library extra |
| `octo`, `smolvla`, `libero` | interactive socket service (`python -m eclise.<pkg> serve`) |
| `pi0` | interactive socket service (`setup_pi0.sh` + `serve_pi0.sh` wrap openpi) |
| `phyworld` | batch producer (`phyworld-phyre` is the PHYRE secondary env) |
| `openvid` | batch producer |
