Run hotl through a gateway — hotl the agent
Point hotl at any OpenAI-compatible gateway (Bifrost, LiteLLM, OpenRouter, a corporate proxy) instead of a provider directly, and optionally obtain the API key from a command instead of an env var. Nothing here is gateway-specific: a gateway is a base URL, and a key is whatever your configured command prints.
Why a gateway
Section titled “Why a gateway”A gateway gives you provider failover, key pools, and spend limits without hotl depending on any of it. hotl composes with a gateway; it does not require one. One rule when you do: leave gateway-side retries off (most default to 0) — hotl’s engine owns retry, backoff, and fallback, and two retry layers multiply.
Point hotl at the gateway
Section titled “Point hotl at the gateway”Any OpenAI-compatible endpoint is just a base URL. In
~/.config/hotl/config.toml:
[provider]model = "openai/claude-opus-4-8" # openai/<model-as-the-gateway-names-it>base_url = "http://localhost:8080/v1" # the gateway's OpenAI-compatible rootOr per-shell: export HOTL_MODEL=openai/<model> HOTL_OPENAI_BASE_URL=http://localhost:8080/v1.
The openai/ prefix selects hotl’s OpenAI-compatible dialect; everything
after it is passed to the gateway verbatim, so use whatever model name the
gateway routes (for multi-provider gateways that is often
openai/anthropic/claude-opus-4-8 — provider prefix included).
Obtain the key from a command (api key helper)
Section titled “Obtain the key from a command (api key helper)”For gateways that issue short-lived or rotating keys, configure a command whose stdout is the key instead of a static env var:
[provider]api_key_helper = "my-mint-key" # stdout (trimmed) = the keyapi_key_helper_ttl_secs = 300 # optional: re-run when older than 5m- Runs at session start (a broken helper fails fast with its own message, before you burn a prompt).
- Re-runs automatically once when the provider answers 401/403, then the request is retried once. A second auth failure surfaces.
- Re-runs when the cached key is older than the TTL (omit the TTL to refresh only at startup and on auth failures).
- A configured helper beats
OPENAI_API_KEY/ANTHROPIC_API_KEY— configuring it is a deliberate act.hotl doctornames the active source. - Constraints: 5 seconds to run, 64KB of stdout, non-zero exit or empty stdout is an error (stderr shows up in the message — print something useful there).
Works identically for Anthropic direct — the helper is a key source, not a gateway feature.
Worked example: Bifrost with a virtual key
Section titled “Worked example: Bifrost with a virtual key”Bifrost is a self-hostable gateway that pools provider keys behind virtual keys. End to end:
# 1. Start the gateway (defaults to :8080).npx -y @maximhq/bifrost
# 2. Configure an upstream provider key + create a virtual key in the web UI# (http://localhost:8080) — or script it against the governance API.# Store the virtual key wherever your secret tooling lives:security add-generic-password -a "$USER" -s bifrost-vk -w "vk-…" # macOS example
# 3. Tell hotl where the gateway is and how to fetch the key.cat >> ~/.config/hotl/config.toml <<'EOF'[provider]model = "openai/anthropic/claude-opus-4-8"base_url = "http://localhost:8080/v1"api_key_helper = "security find-generic-password -s bifrost-vk -w"EOF
# 4. Verify, then run.hotl doctor # expect: key helper: OK — gateway: …/models reachablehotlLeave Bifrost’s MaxRetries at its default 0: the engine owns recovery.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Meaning | Fix |
|---|---|---|
api_key_helper … timed out after 5s |
The helper hung (prompted for input?) | Helpers must be non-interactive; pre-authenticate your secret tool. |
api_key_helper … printed nothing on stdout |
Wrong flag or empty secret | Run the command by hand; it must print only the key. |
gateway: … rejected the key (HTTP 401) in doctor |
Key invalid/expired at the gateway | Mint a new key; check the helper fetches the current one. |
| Model errors mention an unknown model | Gateway routes by its own names | Use the gateway’s model id after openai/, e.g. openai/anthropic/claude-opus-4-8. |