Agent Runtime
os-server doesn't run the conversation itself. It hands every turn (voice or chat) to an agent runtime — a separate process that owns the tool loop, memory, skills and channels. The Intern ships with OpenClaw; the Developer Edition can switch to any of these:
| Runtime | Value | Service | Talks to the LLM as | Channels |
|---|---|---|---|---|
| OpenClaw (default) | openclaw | openclaw | OpenAI Chat Completions (custom URL) / catalog format (Autonomous) | Telegram, Slack, Discord, WhatsApp |
| Hermes | hermes | hermes-gateway | Anthropic Messages | Telegram, Slack, Discord, iMessage |
| Claude Code | claudecode | claudecode | Anthropic Messages | Telegram, Slack, Discord |
| Codex | codex | codex | OpenAI Responses | Telegram, Slack, Discord |
| OpenCode | opencode | opencode | OpenAI Responses | Telegram, Slack, Discord |
| PicoClaw | picoclaw | picoclaw | Anthropic Messages | Telegram |
| Remote Hermes | remote | — (Hermes on another machine on your LAN) | — | — |
Switch runtime
Don't just edit agent_runtime in config.json. A switch installs the
runtime if it's missing, generates its config, starts its service, waits
until it's healthy, stops the old one, and only then saves the choice — and
rolls back if anything fails. Hand-editing the key skips all of that.
Web UI: http://<device-ip>/setting?debug=true#runtime → Runtime →
choose → Switch.
API:
curl -s -X POST $DEVICE/api/device/agent-runtime \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"runtime":"hermes"}'
The call returns immediately (409 if a switch is already running). os-server
restarts at the end, so poll until the new runtime reports ready:
curl -s -H "Authorization: Bearer $TOKEN" $DEVICE/api/device/agent-runtime | jq .data
# → {"current":"hermes","options":[…],"ready":true, …}
The first switch to a runtime downloads and installs it from the internet, so it can take a few minutes. If a switch fails, the log is here:
sudo journalctl -u os-runtime-switch --no-pager -n 200
Remote Hermes
Run Hermes on a bigger machine on your LAN (e.g. your Mac) and let the Intern use it. On that machine:
curl -fsSL https://cdn.autonomous.ai/os/tools/setup-remote-hermes.sh | bash
# prints: Hermes URL : http://<mac-ip>:8642 and an API key
Then point the device at it:
curl -s -X POST $DEVICE/api/device/agent-runtime \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"runtime":"remote","url":"http://192.168.1.20:8642","token":"<hermes-api-token>"}'
See docs/agentic/remote-hermes.md
for the host-side setup.
What carries over when you switch
- LLM settings stay in
config.jsonand are regenerated into the new runtime's own config. Keep editingconfig.json/ the API, not the runtime files (see below). - Persona, channels and MCP tools are migrated into the new runtime.
- Channels the new runtime doesn't support are skipped and listed in
channels_unsupportedinconfig.json(e.g. WhatsApp after switching away from OpenClaw).
Where each runtime keeps its state
| Runtime | Config / state on device | Generated from config.json |
|---|---|---|
| OpenClaw | /root/.openclaw/openclaw.json, workspace /root/.openclaw/workspace/ | models.providers.autonomous.{baseUrl,apiKey,api,models}, agents.defaults.model.primary = "autonomous/<llm_model>" |
| Hermes | /root/.hermes/config.yaml, /root/.hermes/.env | custom_providers[0].base_url, AUTONOMOUS_API_KEY, model.default |
| PicoClaw | /root/.picoclaw/config.json, .security.yml, workspace /root/.picoclaw/workspace/ | api_base (adds /v1), model, api_keys |
| Codex | /root/.codex/config.toml, .env, workspace /root/.codex/workspace/ | [model_providers.autonomous] base_url, model, OPENAI_API_KEY |
| Claude Code | /root/.claudecode/.env, workspace /root/.claudecode/workspace/, /root/.claude/ | ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_MODEL |
| OpenCode | /root/.config/opencode/opencode.json, /root/.opencode/.env | provider campaign → baseURL, {env:LLM_API_KEY}, campaign/<llm_model> |
These generated files are marked "managed — do not edit" and are rewritten on
every boot and switch. Put your LLM settings in config.json.
On the Autonomous proxy, the non-OpenClaw runtimes use the model alias
Auto-AI, which only exists on the proxy. If you point llm_base_url
anywhere else, you must set llm_model too, or every turn fails with a
400.
Subscription login instead of an API key
- Claude Code: set
claude_code_oauth_tokeninconfig.json(or log in withclaudein the Web CLI, which creates/root/.claude/.credentials.json). The runtime then uses your claude.ai subscription and drops theANTHROPIC_*API settings. - Codex: if
/root/.codex/auth.jsonexists (fromcodex login), Codex uses your ChatGPT subscription with the built-in OpenAI provider.
Logs and restart
sudo journalctl -u openclaw -f # or hermes-gateway, claudecode, codex, opencode, picoclaw
curl -s -X POST -H "Authorization: Bearer $TOKEN" $DEVICE/api/agent/restart
Adding your own runtime
A runtime is one folder under runtimes/<name>/ (with install.sh and
presync.sh) plus a case in system/agent/factory.go. See
docs/agentic/adding-agent-runtime.md
and runtimes/README.md.