> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usesynth.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosted Optimizers

> Quickstart for hosted GEPA and GELO runs with the synth-optimizers SDK and CLI.

Hosted Optimizers is the fastest path to run GEPA prompt optimization and GELO exploration jobs on Synth infrastructure. Use `synth-optimizers` from your local machine, point it at a reachable task container, and follow the hosted run until it reaches a terminal state.

## Quickstart

Install the package and configure a Synth API key:

```bash theme={null}
uv add synth-optimizers
export SYNTH_API_KEY="sk_..."
```

Submit a hosted GEPA run from a TOML config:

```bash theme={null}
synth-optimizers gepa submit \
  --config gepa.toml \
  --tunnel-url http://localhost:8765 \
  --tunnel-provider synth_tunnel \
  --follow
```

Submit a hosted GELO run from a preset:

```bash theme={null}
synth-optimizers gelo submit \
  --preset crafter_smoke \
  --tunnel-url http://localhost:8943 \
  --tunnel-provider synth_tunnel \
  --follow
```

`--follow` keeps the local tunnel lease open while the hosted run is active and streams lifecycle events until the run finishes.

## GEPA

GEPA is available both locally and hosted. For hosted execution, provide a GEPA TOML config and exactly one task target:

* `--tunnel-url` for a local task service exposed through a tunnel
* `--container-pool` for an existing hosted pool
* a direct container URL inside the config

Watch an existing hosted GEPA run:

```bash theme={null}
synth-optimizers gepa watch gepa_... --events
```

Python callers can submit the same TOML directly:

```python theme={null}
from pathlib import Path

from synth_optimizers.hosted import HostedOptimizerClient

client = HostedOptimizerClient()

with client.open_tunnel("http://127.0.0.1:8765", provider="synth_tunnel") as tunnel:
    run = client.submit_gepa_toml(
        Path("gepa.toml").read_text(),
        container_tunnel=tunnel,
    )
    result = client.wait_for_run(run.run_id, timeout_seconds=3600)

print(result.status.value)
```

## GELO

GELO is hosted-only in the public package. You can submit from a built-in preset, a materialized JSON config, or a structured TOML/JSON config.

```bash theme={null}
synth-optimizers gelo startup --json

synth-optimizers gelo materialize \
  --preset crafter_smoke \
  --container-url https://your-task-app.example.com \
  -o .out/crafter_goex.json

synth-optimizers gelo submit \
  --config .out/crafter_goex.json \
  --follow
```

Python callers can submit a typed preset:

```python theme={null}
from synth_optimizers.gelo import GeloPreset
from synth_optimizers.hosted import HostedOptimizerClient

client = HostedOptimizerClient()

with client.open_tunnel("http://127.0.0.1:8943", provider="synth_tunnel") as tunnel:
    config = GeloPreset.crafter_smoke().materialize(
        container_tunnel=tunnel,
    )
    run = client.submit_gelo(config)
    result = client.wait_for_run(run.run_id, timeout_seconds=3600)

board = client.get_state_slice(run.run_id, "board")
```

### GameBench Rust presets

GELO can target GameBench Rust task containers through the same hosted submit path:

```bash theme={null}
synth-optimizers gelo submit \
  --preset craftax_gamebench_rust_smoke \
  --tunnel-url http://localhost:8098 \
  --tunnel-provider synth_tunnel \
  --follow
```

`craftax_gamebench_rust_smoke` and `rogue_gamebench_rust_smoke` materialize explicit
`gamebench/<task>/rust` substrate metadata so result packets can distinguish GameBench
Rust runs from legacy Craftax, NLE, or Crafter evidence.

## GELO Launch Promo

The June 26 GELO launch promo gives eligible organizations a hosted Go-Ex
proposer-spend grant for 72 hours after claim. Hosted `go-ex` submits auto-claim
the grant when promo capacity remains, attach the `gelo_launch_promo` Autumn
product, and preflight at least `$1` of `optimizer_go_ex_llm_spend` headroom before
the run is queued. The active campaign id is `gelo_free_72h_20260626`.

The promo applies to hosted proposer spend only. LLM calls made inside your task
container remain owned by that container and its provider credentials.

Promo submits require GPT models for the five paid proposer roles:
`core_proposer`, `aux_hill_climb_proposer`, `aux_data_miner_proposer`,
`aux_consolidate_proposer`, and `aux_consolidate_hill_climb_proposer`.
`theme_verifier_agent` and `terminator_agent` are intentionally exempt. Repeat
submits from the same organization reuse the same promo grant, and each
organization can have one hosted GELO run in `queued` or `running` status at
once while using the promo. Use
`GET /api/v1/optimizers/gelo-launch-promo/status` to inspect slots, grant
state, expiry, and headroom; `POST /api/v1/optimizers/gelo-launch-promo/claim`
is available for explicit pre-claim flows.

## Task Targets

Each hosted optimizer run must target one task service authority:

| Target         | Use when                                                     |
| -------------- | ------------------------------------------------------------ |
| Local tunnel   | You are developing against a local container or task server. |
| Direct URL     | Your task service is already publicly reachable.             |
| Container pool | The task is already registered in Synth container pools.     |

Tunnels support `synth_tunnel`, `cloudflared`, and `ngrok` providers through one parent abstraction. `synth_tunnel` is the default and can refresh backend-owned lease auth during long hosted runs. `cloudflared` and `ngrok` submit as public URLs.

## Usage Registration

Hosted submits send a best-effort usage registration event unless disabled. The event is content-free:

* package name and version
* algorithm (`gepa` or `go-ex`)
* client surface (`sdk` or `cli`)
* event name (`run_submit`)
* source IP derived by the backend

It does not send prompts, configs, code, artifacts, repository paths, run IDs, user IDs, or organization IDs.

Disable it when needed:

```bash theme={null}
SYNTH_OPTIMIZERS_DISABLE_USAGE_REGISTRATION=1 \
  synth-optimizers gelo submit \
  --preset crafter_smoke \
  --container-url https://task.example.com
```

```bash theme={null}
synth-optimizers gelo submit \
  --preset crafter_smoke \
  --container-url https://task.example.com \
  --disable-usage-registration
```

```python theme={null}
client = HostedOptimizerClient(register_usage=False)
```

## GELO Plugin Lanes

GELO plugin lanes are typed so configs can describe training extensions without implying every lane is live.

For this launch, SFT is an invite-only beta lane. RLVR and OPSD are private-evaluation
or waitlist lanes and are rejected by the SDK/API until explicitly enabled.

```python theme={null}
from synth_optimizers.gelo import GeloPluginKind, GeloPreset

config = GeloPreset.crafter_smoke().materialize(
    container_url="https://your-task-app.example.com",
)
config["plugins"] = {"lanes": [{"kind": GeloPluginKind.SFT.value}]}
```

Requests that declare RLVR, OPSD, or an unknown plugin kind fail closed instead of silently downgrading to prompt-only behavior.

## Related

* [Container Pools](/sdk/pools)
* [Tunnels](/sdk/tunnels)
* [Crafter + GELO cookbook](https://github.com/synth-laboratories/cookbooks/tree/main/code/training/prompt_learning/gelo)
