Install
openclaw skills install @mina-atef-00/custom-llm-provider-setupWire any OpenAI-compatible LLM API into Hermes Agent as a custom provider — Cloudflare Workers AI, self-hosted vLLM, Ollama, LM Studio, or any service that implements /v1/chat/completions.
openclaw skills install @mina-atef-00/custom-llm-provider-setupWire any OpenAI-compatible API endpoint into Hermes Agent. The
provider: custom path works with any service that implements
/v1/chat/completions — Cloudflare Workers AI, Ollama, vLLM,
LM Studio, Portkey, AI/ML API, and dozens more.
/v1/chat/completions)If the provider has its own auth (OAuth refresh, token exchange,
non-Bearer scheme), you need a built-in provider or a plugin
instead — see hermes-agent/SKILL.md → Adding Providers.
The custom provider only reads OPENAI_API_KEY from .env when
the endpoint host is openai.com or openai.azure.com. This is a
deliberate host-gated credential guard to prevent leaking your OpenAI
key to arbitrary endpoints (source: hermes_cli/runtime_provider.py).
For any other endpoint (Cloudflare, Ollama, vLLM, LM Studio, etc.)
the API key MUST be in model.api_key inside config.yaml, or in a
named entry under providers:.
model.api_key (simple, single provider)# ~/.hermes/config.yaml
model:
provider: custom
default: "your-model-id"
base_url: "https://your-endpoint/v1"
api_key: "your-api-token"
Set via CLI:
hermes config set model.provider custom
hermes config set model.base_url "https://your-endpoint/v1"
hermes config set model.default "your-model-id"
hermes config set model.api_key "your-api-token"
providers: entry (recommended for multiple)Keeps several endpoints switchable without rewriting config each time:
# ~/.hermes/config.yaml
providers:
my-provider:
model: "your-model-id"
base_url: "https://your-endpoint/v1"
api_key: "your-api-token"
context_length: 131072 # optional: override context window
Switch to it:
hermes config set model.provider my-provider
hermes config set model.default "your-model-id"
Both providers: (newer dict format) and custom_providers: (legacy
list format) are supported.
If your model has a non-standard context window (e.g. Kimi K2.6 has 262k), set it explicitly so Hermes doesn't truncate or use defaults:
hermes config set model.context_length 262144
Or per-provider in the providers: entry.
Before wiring it into Hermes, confirm the endpoint speaks OpenAI format:
curl -s --request POST \
--url "https://your-endpoint/v1/chat/completions" \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/json" \
--data '{
"model": "your-model-id",
"messages": [{"role": "user", "content": "Say hello in one word"}],
"max_tokens": 10
}' | python3 -m json.tool
Expected: {"object": "chat.completion", "choices": [...]}.
If the endpoint has a non-standard URL path (e.g. requires an
account ID in the path, or uses a different prefix), inspect
the provider's OpenAI-compatibility docs — see references/
for per-provider guides.
hermes config set model.default "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
Or use /model inside a running Hermes session.
OPENAI_API_KEY env var is ONLY
forwarded to openai.com / openai.azure.com hosts. For any
other endpoint, use model.api_key in config.yaml or a
providers: named entry (see ⚠️ Critical above).@cf/...,
@hf/...). Use whatever the provider's docs say for model ID./reset or start a new hermes process)."stream": true — on free tiers they can queue for minutes before the first byte, and a non-streaming probe dies with a meaningless timeout. 000 = no HTTP answer at all (inconclusive — retry streaming with a longer cap); 403 = model family not registered for your key (register it via the provider's model page); 404 = deployment not found for your account (dead — exclude the model).200 probe does not prove the model is usable in agent practice. The authoritative tests are hermes chat -Q --provider <p> -m <model> -q "Reply with the single word OK" (the prompt MUST go through -q; a bare positional prompt after -Q is rejected as an unrecognized argument) and, above that, the user's own interactive trials. The user owns the roster decision — present probe results and wait; never auto-commit multi-model architecture (MOA presets, fallback chains) onto models that have not passed a live probe, because a council of models that hang is pure added latency.500 on a bare probe does NOT prove a model is broken. A minimal probe (no tools, no streaming, tiny max_tokens) is not representative of agent traffic — models behind a Responses-API-only transport fail chat_completions probes while working fine in real sessions. Before declaring a model unreachable, check the provider's own model list (absence there is a real verdict; a 500 alone is not), try the other endpoint (/responses vs /chat/completions), and weight real in-session traffic above any probe. Probe failures are probe-scoped findings until corroborated — label them as such in any report, because wrongly calling a working model dead silently removes it from the fleet.--max-time, so a six-model loop can run 10+ minutes.model.* — the full procedure is in references/provider-migration-sweep.md.hermes config set and re-read the final config.yaml to verify every key landed (the CLI silently refuses some protected global keys — retry with --force and diff against your intended values).references/ — per-provider setup recipes and model identity tracingreferences/provider-model-tracing.md — how to discover the underlying model behind an opaque alias (proxy providers, server-routed names, and when to give up)references/provider-migration-sweep.md — full-stack provider migration: backup, sweeping aux/delegation/cron/moa/profile pins, RPM sizing, and the verification chainhermes-agent/SKILL.md — general Hermes configuration reference