Set Up Actual Computer as a Hermes Inference Provider
Set up Actual Computer (actual.inc) inference in Hermes.
Written by Neura Market from the official Hermes Agent documentation for Actual Setup. Commands, paths, and version numbers are reproduced from the source unchanged.
Read the official documentationActual Computer (actual.inc) turns your own hardware into a private inference cluster and exposes an OpenAI-compatible API. This guide walks through wiring it into Hermes Agent as a first-class provider, covering both the hosted relay and the fully local on-device daemon. You will also learn how to avoid the common pitfalls that trip up first-time setups, from empty streams to model naming mismatches.
What it does
The Actual setup skill configures Hermes to route inference requests through Actual Computer. You get two connection modes. The first is a hosted relay at https://api.actual.inc that uses end-to-end encryption and authenticates with an ac_ key. The second is a local daemon running on your own machine at http://127.0.0.1:8080, which requires no authentication on loopback. The skill does not install the Actual daemon for you; device authorization always needs a human in a browser. Once configured, Hermes treats Actual like any other provider, so you can switch models and run chats without changing your workflow.
Before you start
Make sure you have the following in place before running the setup commands.
- Hermes with first-class
actualprovider support. The provider id isactual, with aliasesactual-computer,actualcomputer, andaci. Do not configure Actual as acustom_providersorproviders.actual.*entry on current Hermes. The built-in provider owns the name and handles base-url normalization, the Responses transport, and local no-auth automatically. - For relay mode: an Actual account and an
ac_inference key from https://actual.inc/user/keys. - For local mode: the daemon installed and authorized. Install with
curl -fsSL "https://actual.inc/install" | bash, then runactualonce and open the printedhttps://actual.inc/device?code=...URL in a browser. Relay that URL to the user and wait. Never invent an email or authorize on their behalf. Codes expire in 5 minutes; re-runactualfor a fresh one.
Relay / API mode
This mode connects Hermes to Actual's hosted relay. It is the quickest way to get started if you already have an ac_ key and want to use your cluster without managing a local daemon.
- Put the key in
.env(secrets only, never config.yaml). AppendACTUAL_API_KEY=ac_...to~/.hermes/.env. - Verify the key and discover models with
terminal:
curl -s https://api.actual.inc/v1/models -H "Authorization: Bearer $ACTUAL_API_KEY"
- Select provider and model:
hermes config set model.provider actual
hermes config set model.default "MODEL_ID_FROM_DISCOVERY"
- Verify end-to-end:
hermes chat -Q -q "Reply with exactly: ACTUAL_OK" --provider actual -m MODEL_ID
The curl command should return a JSON list of available models. Pick one and use its id in the config and verification steps. The chat command sends a simple prompt and expects the exact reply ACTUAL_OK, confirming the whole pipeline works.
Local mode
This mode points Hermes at the local daemon, giving you fully on-device inference with no network dependency and no API key. It is the right choice when privacy or offline operation matters more than raw throughput.
- Make sure the daemon is installed and authorized (see Prerequisites).
- Download and load a model. This is scriptable once authorized:
actual models search "qwen2.5 0.5b instruct gguf" --limit 8 --no-prompt
# Downloads REQUIRE an explicit quantization (409 ambiguous_model_download otherwise):
actual models download "Qwen/Qwen2.5-0.5B-Instruct-GGUF/Q4_K_M"
actual models list # note the INSTALLED name (differs from download id)
actual models load "qwen2.5-0.5b-instruct-q4_k_m" # load by installed name
- Point Hermes at the daemon.
ACTUAL_BASE_URLwith a loopback host flips the built-in provider into local no-auth mode automatically, so no key is needed. AppendACTUAL_BASE_URL=http://127.0.0.1:8080to~/.hermes/.env, then:
hermes config set model.provider actual
hermes config set model.default "INSTALLED_MODEL_NAME"
- Verify with a reduced toolset (see the context-window pitfall below):
hermes chat -Q -q "Reply with exactly: LOCAL_OK" --provider actual -m INSTALLED_NAME -t file,web
The search command lists models that match your query. The download command requires an explicit quantization, otherwise you get a 409 error. After downloading, actual models list shows the installed name, which is what you use for loading and for the Hermes model.default setting. The verification command restricts tools to file and web to keep the prompt small enough for a 0.5B model.
Quick Reference
| Thing | Value |
|---|---|
| Hosted relay | https://api.actual.inc/v1 (normalized from bare host automatically) |
| Local daemon | http://127.0.0.1:8080/v1 (no auth on loopback) |
| Key env var | ACTUAL_API_KEY (ac_...) |
| Base URL env var | ACTUAL_BASE_URL (loopback host ⇒ local no-auth mode) |
| Provider id / aliases | actual / actual-computer, actualcomputer, aci |
| Transport | Responses API (codex_responses), built-in, do not override |
| Cluster pinning | X-Cluster-ID header via providers.actual.extra_headers in config.yaml |
| Model size guide | 0.5B Q4_K_M ~470MB (toy), 7-8B Q4_K_M ~4.5GB (daily driver), 32B ~20GB |
Pitfalls
- reasoning_effort trap (handled by Hermes since the first-class provider). Actual's SGLang/vLLM backends accept only
none/low/medium/high/max;xhigh/ultraused to fail with a crypticExpecting value: line 1 column 1 (char 0)(a wrapped HTTP 400). The built-in provider clampsxhigh→highandultra→maxon the wire. If a request still 400s this way on an old Hermes, set a per-model cap:agent.reasoning_overrides.: highin config.yaml. - Context-window overflow on small local models. Hermes' default toolset is ~26k tokens of schemas plus a ~9k-token system prompt. A model loaded with a 32k context overflows before the first turn, and llama.cpp-family servers emit a bare
data: [DONE], Hermes reportsProvider returned an empty stream with no finish_reason. This is NOT an SSE bug. Fixes: restrict tools (-t file,web), load the model with a largern_ctx, or pick a >=64k-context model for the full toolset. Upstream tracking: #51448 (do not file new issues; add evidence there). Related but distinct: #65631 (HTTP-200 SSE carrying a 400), #56516 (reasoning-only streams). - Download ids vs installed names.
actual models downloadtakesrepo/QUANTand 409s without an explicit quantization;actual models loadtakes the INSTALLED name fromactual models list. - Reasoning models returning empty content. GLM/Qwen reasoning variants emit thinking in a separate
reasoningfield and can burn a smallmax_tokensentirely on reasoning. Give generous max_tokens before assuming failure. - Do not create a custom provider named
actual. Older setup guides (pre first-class support) wroteproviders.actual.*config blocks. On current Hermes the built-in provider wins the name; stale custom blocks are ignored or conflict. Remove them and use the env vars + model.provider flow above.
Verification
Run these commands to confirm everything works:
# Relay:
hermes chat -Q -q "Reply with exactly: ACTUAL_OK" --provider actual -m MODEL
# Local (small model — reduced toolset):
hermes chat -Q -q "Reply with exactly: LOCAL_OK" --provider actual -m MODEL -t file,web
# Provider status (local no-auth shows key_source=local-offline):
hermes status
For other OpenAI-compatible clients (e.g. OpenCode), see references/opencode.md.
When not to use it
If you already have a working provider configuration that does not involve Actual, or if you need a provider that Hermes does not support natively, this skill is not for you. Also, if you are on an older Hermes version that lacks first-class actual support, the setup will not work as described; you would need to upgrade or follow legacy guides, which are now discouraged.
Limits and gotchas
The main limitations are the ones listed in the Pitfalls section. The context-window overflow is the most common cause of mysterious empty streams, so always check your model's context size before blaming the connection. The download id versus installed name mismatch is another frequent source of errors. And remember that the skill never automates device authorization; that step always requires a human to open the browser URL.
What pairs with this
For other OpenAI-compatible clients that you might want to point at the same Actual setup, the source documentation points to references/opencode.md. That reference covers using Actual with clients like OpenCode, which is useful if you want to share your cluster across multiple tools.