factor technologies
Gyms

Publish gyms with the CLI

Publish a private gym from a terminal and find gyms by slug. New gyms are visible only to your organization.

You need the CLI signed in with a key that has the publish scope. See Quickstart.

Choose how to publish#

Your gym isCommand
Already installed on the Hubgft env add gft-environment.json
A new pure-Python wheelgft env push dist/my_gym-1.0-py3-none-any.whl --manifest gft-environment.json
A container image or a running servicegft env connect --manifest gft-environment.json --image <digest> or --connection <id>

Publishing is content-addressed, so sending the same package again is safe. The server qualifies every package before it becomes ready.

Write the manifest#

gft-environment.json uses the gft.environment.v1 schema. It has two top-level objects:

Push a wheel#

gft env push uploads a pure-Python wheel with exactly one entry point:

toml
[project.entry-points."gft.environments"]
openenv = "my_gym.app:app"

The ASGI app implements /health, /metadata, /schema, /qualification, /reset, /step, /state, /artifacts and /close. Add --follow to wait for the build.

A separate worker builds the wheel into an isolated sandbox and qualifies it. The API never imports or installs your code. Native wheels and dependency downloads at runtime are rejected.

Connect an image or a service#

gft env connections lists the private connections your administrator registered. Pass one with --connection, or pass an OCI image pinned by a sha256 digest with --image. The image must already be staged on the worker.

Find gyms#

bash
gft env list --ready
gft env list --search sql --family query-rewrite --provider nebius
gft env list --source organization --ready
gft --json env info shopify

training_ready means the gym has an active skill, a training taskset, a reward profile and a runtime. evaluation_ready also requires a held-out taskset and a benchmark protocol.