@bsbofmusic/openclaw-ua-adapter
v0.4.1
Published
A lightweight User-Agent adapter and Hermes-friendly OpenAI-compatible proxy.
Maintainers
Readme
@bsbofmusic/openclaw-ua-adapter
@bsbofmusic/openclaw-ua-adapter is a small helper for OpenClaw and Hermes.
It solves one practical problem: some relays only accept specific client identities. When that happens, OpenClaw or Hermes can get rejected even when the API key and model are correct. This package lets you set the provider User-Agent cleanly, either by updating openclaw.json or by running a small OpenAI-compatible proxy for Hermes.
It is meant to be:
- light
- safe
- easy to rollback
- friendly to existing OpenClaw installs
What it does
By default it writes this UA:
opencode/1.3.0It writes it into the provider config, for example:
{
"models": {
"providers": {
"v2ai": {
"headers": {
"User-Agent": "opencode/1.3.0"
}
}
}
}
}That means it does not need to rewrite OpenClaw internals in the normal case.
Install
npm i -g @bsbofmusic/openclaw-ua-adapterOr run it directly:
npx @bsbofmusic/openclaw-ua-adapter@latest applyMost useful commands
openclaw-ua-adapter apply
openclaw-ua-adapter verify --base-url https://v2ai.cc/v1 --model gpt-5.4 --api-key-env OPENAI_API_KEY
openclaw-ua-adapter rollback
openclaw-ua-adapter heal --base-url https://v2ai.cc/v1 --model gpt-5.4 --api-key-env OPENAI_API_KEYHermes proxy mode
Use serve when the client cannot inject the required upstream User-Agent or when you want Hermes to use a local adapter key while the adapter owns the real upstream key.
OPENCLAW_UA_ADAPTER_UPSTREAM_BASE_URL=https://api.example.com/v1 \
OPENCLAW_UA_ADAPTER_UPSTREAM_API_KEY=sk-your-upstream-key \
OPENCLAW_UA_ADAPTER_USER_AGENT=opencode/1.3.0 \
OPENCLAW_UA_ADAPTER_MODELS=gpt-5.5,gpt-5.4 \
npx @bsbofmusic/openclaw-ua-adapter@latest serveThen point Hermes at the local adapter:
model:
provider: custom
default: gpt-5.5
base_url: http://openclaw-ua-adapter:8787/v1
api_key: adapter-local-key
api_mode: chat_completionsThe adapter accepts Hermes requests at:
GET /health
GET /v1/models
POST /v1/chat/completions
POST /v1/responsesStreaming responses are passed through chunk-by-chunk. The adapter must not buffer SSE output because Hermes and Discord clients expect partial tokens quickly.
It forwards to the upstream paths without duplicating /v1, so /v1/chat/completions becomes <upstream>/chat/completions when the upstream base URL already ends in /v1.
Docker Compose Example
services:
openclaw-ua-adapter:
image: node:22-alpine
command: sh -lc "npx -y @bsbofmusic/openclaw-ua-adapter@latest serve"
environment:
OPENCLAW_UA_ADAPTER_UPSTREAM_BASE_URL: https://api.example.com/v1
OPENCLAW_UA_ADAPTER_UPSTREAM_API_KEY: ${UPSTREAM_API_KEY}
OPENCLAW_UA_ADAPTER_USER_AGENT: opencode/1.3.0
OPENCLAW_UA_ADAPTER_MODELS: gpt-5.5,gpt-5.4
restart: unless-stoppedFor compatibility with earlier one-off deployments, these legacy env names also work: UPSTREAM_BASE_URL, UPSTREAM_API_KEY, UPSTREAM_USER_AGENT, UPSTREAM_EXTRA_HEADERS, and UPSTREAM_MODELS.
Recommended VPS usage
If your machine has more than one OpenClaw home, pass the real gateway config path explicitly:
openclaw-ua-adapter apply \
--config-path /var/lib/openclaw/.openclaw/openclaw.json \
--provider v2ai \
--ua opencode/1.3.0This is usually safer than relying on auto-detect.
Extra headers
If your relay also needs extra headers, you can add them:
openclaw-ua-adapter apply \
--header "X-Client-Name=opencode"Or use JSON:
openclaw-ua-adapter apply --headers-json '{"X-Client-Name":"opencode"}'Runtime fallback mode
Normally this package only edits openclaw.json.
If that is not enough, it also has a runtime fallback mode that patches the bundled OpenAI client directly:
openclaw-ua-adapter apply-runtime --target /opt/openclaw-runtime/node/lib/node_modules/openclaw/node_modules/openai/client.jsUse that only when the config route is not enough.
Safety
- Creates a backup before writing config
- Restarts
openclawby default on Linux - Supports
rollback - Supports
healto try candidate UAs - Does not write custom root-level config keys
Release
npm run smoke
npm pack
npm publish --access public