Skip to main content
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:
uv add synth-optimizers
export SYNTH_API_KEY="sk_..."
Submit a hosted GEPA run from a TOML config:
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:
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:
synth-optimizers gepa watch gepa_... --events
Python callers can submit the same TOML directly:
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.
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:
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")

GELO Launch Promo

The GELO launch promo gives the first 20 organizations a $500 hosted Go-Ex proposer-spend grant, valid for 14 days after claim. Hosted go-ex submits auto-claim the grant when slots remain, 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 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:
TargetUse when
Local tunnelYou are developing against a local container or task server.
Direct URLYour task service is already publicly reachable.
Container poolThe 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:
SYNTH_OPTIMIZERS_DISABLE_USAGE_REGISTRATION=1 \
  synth-optimizers gelo submit \
  --preset crafter_smoke \
  --container-url https://task.example.com
synth-optimizers gelo submit \
  --preset crafter_smoke \
  --container-url https://task.example.com \
  --disable-usage-registration
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 the accepted beta lane. RLVR and OPSD are reserved future lanes and are rejected by the SDK/API until explicitly enabled.
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.